# ハッシュによる最適化戦略 アルゴリズムの問題では,**線形探索をハッシュ探索に置き換えることでアルゴリズムの時間計算量を下げることがよくあります**。ここでは,あるアルゴリズム問題を通じて理解を深めましょう。 !!! question 整数配列 `nums` と目標要素 `target` が与えられたとき,配列内から和が `target` となる 2 つの要素を探索し,それらの配列インデックスを返してください。任意の 1 つの解を返せば十分です。 ## 線形探索:時間と引き換えに空間を節約 考えられるすべての組み合わせを直接走査することを考えます。次の図に示すように,2 重ループを開始し,各ラウンドで 2 つの整数の和が `target` であるかを判定します。そうであれば,それらのインデックスを返します。 ![線形探索で 2 数の和を求める](replace_linear_by_hashing.assets/two_sum_brute_force.png) コードは次のとおりです: ```src [file]{two_sum}-[class]{}-[func]{two_sum_brute_force} ``` この方法の時間計算量は $O(n^2)$ ,空間計算量は $O(1)$ であり,大規模データでは非常に時間がかかります。 ## ハッシュ探索:空間と引き換えに時間を節約 ハッシュテーブルを利用し,キーと値をそれぞれ配列要素と要素のインデックスにします。配列をループで走査し,各ラウンドで次の図に示す手順を実行します。 1. 数値 `target - nums[i]` がハッシュテーブル内にあるかを判定します。あれば,この 2 つの要素のインデックスを直接返します。 2. キーと値の組 `nums[i]` とインデックス `i` をハッシュテーブルに追加します。 === "<1>" ![補助ハッシュテーブルで 2 数の和を求める](replace_linear_by_hashing.assets/two_sum_hashtable_step1.png) === "<2>" ![two_sum_hashtable_step2](replace_linear_by_hashing.assets/two_sum_hashtable_step2.png) === "<3>" ![two_sum_hashtable_step3](replace_linear_by_hashing.assets/two_sum_hashtable_step3.png) 実装コードは次のとおりで,単一ループだけで済みます: ```src [file]{two_sum}-[class]{}-[func]{two_sum_hash_table} ``` この方法ではハッシュ探索によって時間計算量を $O(n^2)$ から $O(n)$ に下げ,実行効率を大幅に向上させます。 追加のハッシュテーブルを維持する必要があるため,空間計算量は $O(n)$ です。**それでも,この方法は全体として時間と空間の効率のバランスがより良く,本問の最適解です**。