amtoaer

晓风残月

叹息似的渺茫,你仍要保存着那真!
github
x
telegram
steam
nintendo switch
email

GoLandの完璧なleetcode問題解決体験

大学 2 年生くらいから、少しずつ leetcode の問題を解いてきました。最初は Java を使っていましたが、しばらくしてからはほとんど Go を使っていました。問題を解く過程で、私の解法は大きく変化しました。

最初は leetcode のオンラインエディタを使って問題を解いていましたが、問題が非常に簡単な場合はまだ良かったですが、少し複雑な場合はライブラリをインポートする必要があり、オンラインエディタの自動補完がイライラすることがありました... それほど時間が経たないうちに、私はこの最も原始的な問題解決方法をやめました。

ちなみに、技術の採用試験では、ウェブエディタでの筆記試験が行われることが非常に多いです。

普段はオンラインエディタを使わないのは便利ですが、それによって IDE を離れると何もわからなくなり、標準ライブラリの関数名も忘れてしまうようなツール型の選手にならないようにしましょう!

オンラインエディタを使わない場合、考えられる方法はローカルでプログラムを書くことだけです。最初は vscode + golang 拡張機能を使っていましたが、毎回以下の手順が必要でした:

  1. 問題の名前で新しいコードファイルを作成する。
  2. leetcode の問題の説明を開き、コードテンプレートをコピーする。
  3. アルゴリズムを実装し、コピーしたコードをオンラインエディタに貼り付けてテストを実行する。
  4. テストに合格しない場合は、手順 3 を繰り返す。

繰り返し作業はイライラするものですので、私はvscode-leetcode 拡張機能を見つけました。この拡張機能を使うと、vscode で問題の一覧を表示し、問題を選択すると自動的に問題のプレビューとファイルの説明とテンプレートが生成されるようになりました。これにより、私の作業量が大幅に削減されました。

しかし、ある時点で go や vscode のアップデートが行われ、vscode 内での go の自動補完チェックがフォルダレベルに拡大されました。(おそらく gomod の導入と関連しているのか、私はよくわかりません)問題ごとに異なるフォルダにある構造体や関数の名前が重複すると、重複宣言のエラーが発生し、数百の解答を保存しているフォルダでの壊滅的な災害を引き起こしました。私のソースコードのほぼ半分が赤く表示され、赤い波線を見るたびに身体的な不快感を感じました。

今思えば、leetcode 拡張機能のドキュメントをもっと調べるべきでした。もしかしたら何か解決策があるかもしれませんね?

時間はあっという間に過ぎ、卒業して仕事を始めました。仕事では主に Python を使用していますが、普段はまだ Go を書くことが多いです。最近、数人の同僚が LeetCode の連続登録コンテストに参加すると言っていたので、私も参加しました。今回は vscode ではなく、goland を使って、完璧な LeetCode の問題解決環境を構築することにしました。

以下は私の設定手順と考え方です:(長々と話して重要な点にたどり着いたようです。

LeetCode の問題解決プラグインのインストール#

vscode と同様に、GoLand にも同様の問題解決プラグインがあります。その名前は LeetCode Editor です。

ソースコードフォルダの整理#

拡張機能をインストールした後、設定で leetcode の問題の説明とソースコードのテンプレートのダウンロード先を調整できます。設定で場所を/home/amtoaer/Documents/code/に設定したと仮定します。

ランダムな問題をクリックすると、実際のディレクトリ構造が次のようになります:

# この時点で /home/amtoaer/Documents/code/ にいます
./leetcode/
└── editor
    ├── cn
    │   └── doc
    │       └── content
    │           └── 1302.层数最深叶子节点的和
    └── en

つまり、中国語で問題を解く場合、拡張機能のTempFilePath$DIRに設定した場合、実際のソースコードの場所は$DIR/leetcode/editor/cn/になります。また、このディレクトリには問題の説明を保存するための余分なdocフォルダもあります。

ソースコードファイルを保存する必要がある場合は、このディレクトリに移動してください。

私のように問題を git リポジトリにアップロードする場合は、/leetcode/editor/cn/に git リポジトリを作成し、そのフォルダに.gitignoreファイルを作成し、次の行を追加します:

doc

問題の説明文書が含まれるフォルダを無視するように設定します。

同じフォルダ内の名前の衝突エラーの解決#

関連情報を調査した結果、次のいずれかの操作をソースコードファイル内で行うと、go build がそのファイル情報を無視することがわかりました:

  1. ソースコードファイル名の前にアンダースコア _ を追加する。
  2. ソースコードファイル内に //go:build ignore を記述する。

しかし、これらの方法には致命的な欠点があります。GoLand のエディタのヘッダーに閉じることのできない目立つ識別子が表示されるため、完璧主義者の私たちには受け入れられません。

引き続き情報を調査し、leetcode editor 拡張機能がカスタムコードファイルテンプレートとパスをサポートしていることがわかりました。また、 #304 では、パス区切り記号をカスタムファイル名に追加することで新しいフォルダを作成できると述べられています。

ソースコードファイルを単一のフォルダに配置すると、名前の衝突エラーが発生するため、各ソースコードファイルに新しいフォルダを作成することができます。

まず、「Custom Template」オプションを選択し、Code FileNameを次のように変更します:

$!{question.frontendQuestionId}.${question.title}/solution_test

これにより、次のようなファイル構造になります:

├── 102.二叉树的层序遍历
│   └── solution_test.go
├── 103.二叉树的锯齿形层序遍历
│   └── solution_test.go
├── 104.balabala
│   └── solution_test.go

これで、個々のコードファイルの名前が分離されるようになりました。

デバッグのしやすさ#

拡張機能のカスタムコードテンプレート機能と領域コードの提出メカニズムのおかげで、コードのデバッグが非常に簡単になりました。

領域コードの提出:拡張機能は、提出位置の開始点と終了点として 2 つの固定のコメントを維持し、提出時にはこれらのコメント間のコードのみが提出されます。

デバッグ部分(テストケースや main 関数など)を提出領域の外に配置すると、提出されるコードには影響を与えません。

以下は簡単なテンプレートの例で、これを leetcode プラグインの設定のCode Templateに入力する必要があります:

package leetcode

import(
    "testing"
)

${question.content}

${question.code}

func Test$!velocityTool.camelCaseName(${question.titleSlug})(t *testing.T){
    
}

これにより、テスト関数内にサンプルの入力と出力を書き込むだけで、実行ボタンをクリックすることができます。

以下はこのテンプレートで生成されたファイルの例です:

package leetcode

import(
    "testing"
)

//给你一个正整数数组 nums,请你帮忙从该数组中找出能满足下面要求的 最长 前缀,并返回该前缀的长度: 
//
// 
// 从前缀中 恰好删除一个 元素后,剩下每个数字的出现次数都相同。 
// 
//
// 如果删除这个元素后没有剩余元素存在,仍可认为每个数字都具有相同的出现次数(也就是 0 次)。 
//
// 
//
// 示例 1: 
//
// 
//输入:nums = [2,2,1,1,5,3,3,5]
//输出:7
//解释:对于长度为 7 的子数组 [2,2,1,1,5,3,3],如果我们从中删去 nums[4] = 5,就可以得到 [2,2,1,1,3,3],里面每个数
//字都出现了两次。
// 
//
// 示例 2: 
//
// 
//输入:nums = [1,1,1,2,2,2,3,3,3,4,4,4,5]
//输出:13
// 
//
// 
//
// 提示: 
//
// 
// 2 <= nums.length <= 10⁵ 
// 1 <= nums[i] <= 10⁵ 
// 
//
// Related Topics 数组 哈希表 👍 64 👎 0


//leetcode submit region begin(Prohibit modification and deletion)
func maxEqualFreq(nums []int) int {

}
//leetcode submit region end(Prohibit modification and deletion)


func TestMaximumEqualFrequency(t *testing.T){
    
}

ファイル内でアルゴリズムを実装し、ローカルでデバッグする例は以下のようになります:

rBAAdmL9Ho-ATTS6AAmiD_GXDZ0282

これで、この方法はほぼ完璧になりました。

既存のコードリポジトリの移行#

以前のコードはデバッグを続けることはありませんが、まだ価値があります。それらを同じディレクトリ構造に整理することにしました。

  1. 上記の手順に従って leetcode editor プラグインを設定します。

  2. 平坦なコードリポジトリをクローンし、すべてのコードと.gitフォルダを$DIR/leetcode/editor/cn/に移動します。

  3. ソースコードの移行に使用する簡単な Python スクリプトを作成します:

    import os
    
    files = os.listdir('.')
    
    for file in files:
        items = file.rsplit('.', 1)
        if len(items) != 2:
            continue
        name, extension = items
        if extension != 'go':
            continue
        os.mkdir(name)
        os.rename(file, f'{name}/solution_test.go')
    
  4. git add & git commit & git push

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。