Leetcode #1 Two Sum
题目大意
给定一个整数数组(Integers Array),让你找出两个数 使得他们的和正好等于给定的值(Target),返回这两个数的下标。保证只有唯一解题目分析
这个题目题意清晰,要注意两点:- 返回下标,而不是数字本身,且下标是升序的。
- 只有唯一解(这给我们带来了很大便利)
解法
我们很直接就能想到暴力解法(Brutal Force):
利用二维循环,去扫描每一个数,找到的即为答案,注意这种办法在解不唯一且要 输出所以解的时候也适用。很显然,这个暴力算法的- 时间复杂度(Time Complexity)是 O(n2)
- 空间复杂度是(Space Complexity) 是 O(1) ,因为算法运行并没有利用额外的空间
伪代码如下:
for(i=0;i<ArrayLen;i++) for(j=0;j<ArrayLen;j++) { if(Array[i] + Array[j] == Target) { //return i,j } }
利用Hashmap 将我们有什么数存下来,当遇到一个数的时候,直接去存的地方看看它配对的那个数(Target - CurrentNumber)以前出现过没有,如果出现过,则找到了答案,否则将这个数也加入hashmap,继续往下找。不过Hashmap实现的时候不同语言就有不同的办法了。
Python
Python 的内建类型set 和dict是利用hash 实现的 所以查找的复杂度为 O(1) .
而list 的查找并不是基于has key,所以复杂度近似为 O(n) ,并不能提高算法效率。C++
利用 map即可C
以上两种语言(还有java等等)都是利用自带或者库里的方法直接实现hash,可是对于C语言来说,hash 就需要自己实现了。- 首先,我们需要确定hash key对于一个数字value如何在
O(1)
时间内确定它在table里的位置。这里需要一个map functon即
F(value)=index - 最简单的映射函数就是用value 直接作为下标,为了节省些许空间和处理负数,可以对坐标作关于最小值的线性变换
- 通常映射函数是 f(value)=valuemodn n通常选一个质数来减少冲突。当冲突发生了,可以采用open(把它往后面空的地方丢)、close(下拉一个链表存所有下标一样但值不一样的数) 或者用双hash表。在此不再赘述
- 首先,我们需要确定hash key对于一个数字value如何在
O(1)
时间内确定它在table里的位置。这里需要一个map functon即
4.代码
def twoSum(self, nums, target): NumHash = {} for index, cur_num in enumerate(nums): need_num = target - cur_num if need_num in NumHash: return [NumHash[need_num], index] else: NumHash[need_num] = index
未来有机会补上C和C++ 代码
5.总结思考
首先如果解不唯一,需要输出所有解或者最小的解(下标之和),还有没有 O(n) 的办法,该怎么写呢。
可以尝试用C 实现hash,来理解几种冲突的解决办法