图解两数之和:哈希表法

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

相关文章
相关标签/搜索