圖解兩數之和:哈希表法

image

兩數之和是一道很是經典,也很是高頻的面試題,題目大意以下:面試

給定一個整數數組 nums 和一個目標值 target,請你在該數組中找出和爲目標值的那兩個整數,並返回他們的數組下標。
case:
給定 nums = [2, 1, 7, 11, 15], target = 9
由於 nums[0] + nums[2] = 2 + 7 = 9
因此返回 [0, 2]

今天咱們就一塊兒探討一下這道題的解法。算法

太長不看版

  • 能夠經過暴力運算,遍歷nums中的每個元素,查找數組剩餘部分是否有匹配的值;
  • 更高效的方式是利用哈希表key惟一且訪問快的特性,創建map存儲未命中的值。遍歷nums中的元素,查找map上是否有匹配的目標值,不然將當前元素存儲到map上。

暴力運算法

暴力運算法很簡單,經過首層for循環遍歷數組中的每一個元素curr,再經過另一層for循環尋找target - curr值。數組

代碼以下:數據結構

image

雙層for循環致使暴力運算法時間複雜度爲 O(n2),在2020年的今天着實不能令大部分人滿意。spa

哈希表法

哈希表(也叫散列表)是一種數據結構,其定義以下:code

哈希表是根據關鍵字(Key value)而直接訪問在內存存儲位置的數據結構。

咱們能夠把它理解爲詞典,詞典裏的每一個詞條都是惟一的,在這個詞條後面記錄着詞條的含義。就像查詞典時咱們可以很快速的定位到詞條,哈希表的訪問速度也很是快,其時間複雜度爲O(1)。對象

JavaScript中常規的鍵值對對象就是哈希表的實現。blog

接下來咱們就結合題目中的case經過圖解的方式來講明哈希表法如何計算兩數之和。索引

0.初始化

初始化時咱們會拿到nums數組[2, 1, 7, 11, 15]target9,同時map初始化爲空對象{}用於存放未匹配成功的鍵值對:ip


image


接下來將遍歷nums數組。

1.開始遍歷數組

遍歷開始,此時:

  • 當前map爲空{}
  • 當前索引值index0;
  • 當前索引對應的數值curr2;
  • 咱們但願找到target - currneed值爲7

image


由於此時map{},因此map[need]值爲undefined


image


2.保存未匹配成功的值至map

由於所求爲兩數之和,因此哪怕nums[0]的值等於target,迭代第一步必然匹配失敗。


image


此時將未能成功匹配的currindex存放到map中。這一步很是重要,是整個解法的關鍵:

map[curr] = index;

這裏使用curr作爲key,由於咱們須要返回的結果是配對成功的數字其下標所構成的數組,匹配時是在map查找數字、返回下標。

3.繼續遍歷數組

匹配未成功,重複第一步,繼續遍歷數組:


image


一樣未找到指望值need,繼續將currindex寫入map


image


繼續重複此步驟直至匹配成功。

4.匹配成功!

繼續遍歷nums,此時need2curr7,終於在map中查找到了need,隔空會師成功!


image


返回結果:[map[need], index]map[need]在前的緣由是map裏存儲的值,其下標必定在curr對應的下標以前。

5.完整示例代碼

image

  • 哈希解法每次查找的時間複雜度是O(1),n次查找的時間複雜度O(n);
  • 空間複雜度也是O(n),map上最多存n個元素。

小結

  • 雙層for循環暴力運算簡單直觀,時間複雜度O(n2)、空間複雜度O(1);
  • 哈希表法時間複雜度和空間複雜度都是O(n);
  • 考察點是對哈希表這種數據結構的熟悉程度;
  • 多一種解法就多一分勝算;
  • 總體難度不高。

一入JS深似海,但願這個專欄能在你乘風破浪的旅途中有所幫助。歡迎關注個人公衆號:「JS漫步指南」,更多精彩等待您發現!

image

相關文章
相關標籤/搜索