经典的OJ题,放假了,刷这题作为开始。
题目:
给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。
你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
我的解答:
第一个想到的自然是暴力解法:
class Solution {
public int[] twoSum(int[] nums, int target) {
int[] results = {0, 0};
for (int i = 0; i < nums.length - 1; i++) {
for (int j = i + 1; j < nums.length; j++) {
int sum = nums[i] + nums[j];
if (sum == target) {
results[0] = i;
results[1] = j;
}
}
}
return results;
}
}
然而看到网上的解答后,才知道是可以用哈希表优化速度,于是又写了一个:
class Solution {
public int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> map = new HashMap<>();
int[] result = {0, 0};
for (int i = 0; i < nums.length; i++) {
map.put(nums[i], i);
}
for (int i = 0; i < nums.length; i++) {
int v = target - nums[i];
if (map.containsKey(v) && i != map.get(v)) {
result[0] = map.get(v);
result[1] = i;
}
}
return result;
}
}
其实还可以更快的,将加入hash表和判断放入同一个循环:
class Solution {
public int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> map = new HashMap<>();
int[] result = {0, 0};
for (int i = 0; i < nums.length; i++) {
int v = target - nums[i];
if (map.containsKey(v) && i != map.get(v)) {
result[0] = map.get(v);
result[1] = i;
}
map.put(nums[i], i);
}
return result;
}
}
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2019.8.21更新
一年了,第二遍刷LeetCode,顺便也复习下原题。这里用Python 3写(还不是为了防止自己偷看以前blog……)
不过一开始还是只能想到解法,但是这次直接给我TLE超时。
我开始思考,这题的核心点是什么?为什么明明写过一遍的题还是不明白?
哪怕我看到了提示:“hash表”这几个字,还是想不出来到底为啥要用hash表?这题和hash表什么关系?
这次在我的实现代码里面,记录下了我所有的思路。
才发现实际上我首先要把这个题变一下形:
这个题不是要去考虑怎么求和,而是要考虑对于每一个数n,怎么在这给定的数组中间找到一个(target-n)的另一个数!
然后哪怕第一次仍然写的是个暴力方法,后期也可以自然地去想到hash表加快查找速度。
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
'''
leetCode都改的我不认识了呢。
但是我跟去年刚刷的时候一个感觉啊!完全是脑子一片空白呢
不过就是再恶心也要先把暴力的解法交出来呢
Python也不是很熟,先练练手吧。
据说Python只要一行就能搞定呢。
第一次提交:WA
连这种题都能WA的我也是个小白呢,细节错误真的很伤啊
第二次提交:TLE
看来O(n^2)的暴力算法在Python这里不行呢。
又只能偷看题解了呢。
这个地方到底要怎么想呢?
这里我要换一个思路,
一开始我想的是找到求和的所有方式,自然就成了O(n^2)
如果我从另一个角度思考,
那就是对于每一个数i,都在这个给定的数组去找target - i的另一个数,
这样才可能想到hash呢(都是套路啊!或许我唯一的办法就是记住这个套路了)。
我首先就先把这东西弄成一个Hash表吧,因为hash表找东西快呢。
写Java写习惯了的人表示Python那个类似HashMap的是什么东西?
对了,字典dict!
那么接下来就要考虑key和value都是些什么东西了。
题目要输出的是索引
应该key是数值,value是索引呢。
然后因为语法不熟悉,只能疯狂百度用法…
'''
hash_map = {}
for index, num in enumerate(nums):
another_num = target - num
if another_num in hash_map:
return [hash_map[another_num], index]
hash_map[num] = index
return None;