Two Sum をハッシュマップで解く

整数の並びから、足すと目標の数になる 2 つを探し、その位置を返す。見た数を辞書に覚えておくと、並びを 1 回なめるだけで見つかります。

海外で定番の問題リスト 4 本のうち 4 本に入っています (Blind 75、NeetCode 150、Grind 75、LeetCode Top Interview 150)

問題

整数の並び nums と、整数 target を受け取ります。nums の中から、足すと target になる 2 つの数を選び、その位置 (0 から数えた番号) を小さい順に並べて返す関数を書いてください。

  • 答えになる組は、ちょうど 1 組だけあるものとします
  • 同じ位置の数を 2 回使うことはできません。同じ値が別の位置に 2 つあれば、その 2 つは使えます
  • nums の長さは 2 以上 10000 以下、値はどれも絶対値が 10 億以下です

入力と出力の例

例 1

nums = [3, 8, 12, 5] target = 17
[2, 3]

例 2

同じ値でも、位置が違えば別の数として使えます。

nums = [6, 1, 6] target = 12
[0, 2]

例 3

負の数も入ります。

nums = [-4, 10, 7, 2] target = 3
[0, 2]

面接での聞かれ方

面接では、問題文がもっと短く渡されることが多いです。

  • 「整数の配列と目標の数があります。足して目標になる 2 つの位置を返してください」
  • 書き終えたあとに「いまの書き方の計算量は?」「もっと速くできますか?」と続けて聞かれます
  • 「答えが無いときはどうしますか?」と、問題文に無い場合を聞かれることもあります

最初の一文だけで書き始めず、答えがいつも 1 組あるのか、同じ位置を 2 回使ってよいのかを、先に確かめてから書くと落ち着いて進められます。

ヒント

まだ開いていません

付箋は 3 枚。下の段ほど答えに近づきます

  1. ヒント 2

  2. ヒント 3答えに近い

アルゴリズムのチートシートの「ハッシュマップ」に、この型の要点を表とコードでまとめています。

ハッシュは、値から番地を計算して、探す手間をほぼ 1 回にする仕組みです。重複や回数の問題は、この形で解けます。

main.py
def pair_with_target(nums: list[int], target: int) -> list[int]:
    """
    Goal: 何を返すか

    idea1: まず思いつく案
    -> runtime: O(?)  space: O(?)

    idea2: もっと速い案
    -> runtime: O(?)  space: O(?)

    edge case: 空、1 つだけ、など
    """
    # ここに書きます
    pass


# 「実行」を押すと、この行の結果が出ます
print(pair_with_target([3, 8, 12, 5], 17))

できているか「例で確かめる」を押すと、問題の例を全部この関数に渡して、通ったかをここに出します