LeetCodeのJavaScriptの問題のやり方と1問目の解答例

LeetCodeとは

コーディング問題を解く練習と技術面接の準備をするためのWebサイト。

問題はJavaScriptで回答することもできる。

LeetCodeの問題の表示方法

まずLeetCodeのサインアップのWebページに行ってアカウントを作成する。

Google, GitHub, Facebookなどのアカウントも使えるのでサインインはすぐにできる。

サインイン後に画面左上のProblemsをクリックすれば問題一覧ページに遷移する。

難易度(Difficulty)はEasy, Normal, Hardの3種類があるが、Easyでも初心者向けというわけではないので、一通りの基礎知識をしっかりと身に付けていなければ回答は困難だろう。

LeetCode Problems

1問目のJavaScriptの解説と解答例

どのように使うのかLeetCodeの1問目の解説と解答例を交えて説明します。

まず1問目の「1. Two Sub」を選択してください。

選択したら下図のような画面が表示されるので言語をJavaScriptに切り替える。

左側に問題内容が表示されるので回答をコードエディタ内に記述して右下のRun Codeで試して問題ないと思ったらSubmitを押して送信する。

LeetCode 1問目のJavaScriptの解説と解答

無料版だとAutocompleteやDebuggerが使えないのでVS Codeを使ったほうがコードの記述とデバッグがやりやすいだろう。

第1問目はtwoSubにnums, targetの引数がある関数を入れて以下の条件を満たすコードを書く問題。

Example 1:
Input: nums = [2,7,11,15], target = 9
Output: [0,1]

Example 2:
Input: nums = [3,2,4], target = 6
Output: [1,2]

Example 3:
Input: nums = [3,3], target = 6
Output: [0,1]

例えば以下のように単純にfor ... ofを使用してiとnumsを配列で返すと[0,2]となり、Example 1のOutput: [0,1]とは異なるので不正解となる。

const twoSum = (nums, target) => {
  for (const [i, num] of nums.entries()) {
      return [i, num]
  }
}

※ for ... of や entries() などが理解できなければLeetCodeをやるには基礎知識不足です。

わかりやすくVS Code側でJavaScriptで以下のように書いてみるとそれぞれ[0,2]、[0,3]、[0,3]となるため、正解の[0,1]、[1,2]、[0,1]とは1つも合っていないことがわかる。

const twoSum = (nums, target) => {
  for (const [i, num] of nums.entries()) {
    return [i, num]
  }
}

const JS = JSON.stringify
const input1 = [[2, 7, 11, 15], 9]
const input2 = [[3, 2, 4], 6]
const input3 = [[3, 3], 6]
const output1 = JS([0, 1])
const output2 = JS([1, 2])
const output3 = JS([0, 1])

console.log(twoSum(...input1)) // [0, 2]
console.assert(JS(twoSum(...input1)) === output1, 'Example 1 error')
console.log(twoSum(...input2)) // [0, 3]
console.assert(JS(twoSum(...input2)) === output2, 'Example 2 error')
console.log(twoSum(...input3)) // [0, 3]
console.assert(JS(twoSum(...input3)) === output3, 'Example 3 error')

次にExample 1だけに注目してconsole.log[i, num]を見てみる。

const twoSum = (nums, target) => {
  for (const [i, num] of nums.entries()) {
    console.log([i, num])
  }
}

const JS = JSON.stringify
const input1 = [[2, 7, 11, 15], 9]
const output1 = JS([0, 1])
console.assert(JS(twoSum(...input1)) === output1, 'Example 1 error')

すると結果は以下のようになり、「iが1のときの7(num)」が「9(target)からiが0のときの2(num)を引いたもの」と同じになっていることがわかる。

つまりオブジェクトを使ってobj["7"] = 0を保存すればiが1のときのobj[num]が0なので[obj["7"], i]が[0, 1]になる。

[0, 2]
[1, 7]
[2, 11]
[3, 15]

前述の理論をJavaScriptで書くと以下のようになる。

最初はobj[target - num] = iで格納する必要があるので、すぐにreturnせずに「if (obj[num] >= 0) { ... }」の条件分岐も入れておく。

const twoSum = (nums, target) => {
  const obj = {};
  for (const [i, num] of nums.entries()) {
    if (obj[num] >= 0) {
      return [obj[num], i]
    }
    obj[target - num] = i
  }
}

const JS = JSON.stringify
const input1 = [[2, 7, 11, 15], 9]
const input2 = [[3, 2, 4], 6]
const input3 = [[3, 3], 6]
const output1 = JS([0, 1])
const output2 = JS([1, 2])
const output3 = JS([0, 1])

console.log(twoSum(...input1)) // [0, 1]
console.assert(JS(twoSum(...input1)) === output1, 'Example 1 error')
console.log(twoSum(...input2)) // [1, 2]
console.assert(JS(twoSum(...input2)) === output2, 'Example 2 error')
console.log(twoSum(...input3)) // [0, 1]
console.assert(JS(twoSum(...input3)) === output3, 'Example 3 error')

実際に実行してみるとconsole.logの結果は[0, 1], [1, 2], [0, 1]となりconsole.assertのエラーも出ないためコードが正しいことが確認できる。

あとは以下の部分だけLeetCode側に貼り付けてSubmitを押せば回答完了です。

const twoSum = (nums, target) => {
  const obj = {};
  for (const [i, num] of nums.entries()) {
    if (obj[num] >= 0) {
      return [obj[num], i]
    }
    obj[target - num] = i
  }
}

Submitで送信後、問題がなければSuccessと表示されます。

他の問題も同様の手順で回答してみてください。

LeetCode Submitで送信後、問題がなければSuccessと表示