本题来自力扣官网
难度:简单
给定一个整数数组
nums
和一个目标值target
,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
示例:
给定 nums = [2, 7, 11, 15], target = 9 因为 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1]
说说我的想法。首先第一眼看到这个题目,想到的就是直接for循环,两层for循环解决问题(后来看解答发现这种解法为"暴力解法")。
class Solution {
public int[] twoSum(int[] nums, int target) {
for (int i = 0; i < nums.length; i ++) {
int numI = nums[i];
/**
* 原先我在这里还做了一个判断
* if (num >= target) continue;
* 后来发现这里遇到了目标值和元素相等或者元素中有和目标值有负数的时候会出现问题,当时写的时候也是没有考虑到这个情况,只想着减少循环次数
*/
for (int j = nums.length -1; j > i; j --) {
int numJ = nums[j];
if (numI + numJ == target) return new int[] {i, j};
}
}
return null;
}
}
提交之后看一下结果
可以看出暴力解法的时间复杂度特别高:O(n2),所以代码执行的时间特别的久,仅超过了不到20%的用户。
然后我去看了一下官方的解题方法,除了暴力法之外,剩下的就是 哈希表 。
使用哈希表来解:
class Solution {
public int[] twoSum(int[] nums, int target) {
int length = nums.length;
Map<Integer, Integer> map = new HashMap<>(length);
for (int i = 0; i < length; i ++) {
int num = nums[i];
int tmp = target - nums[i];
// 如果结果已经在哈希表中了,则直接返回结果
if (map.containsKey(tmp)) return new int[] {map.get(tmp), i};
// 如果不存在的话则将结果和下标保存到哈希表中
map.put(num, i);
}
return null;
}
}
(这一次应该是最好的一次结果,一般的执行时间为6ms,内存消耗在37-38MB之间)
通过 哈希表 ,我们可以看出我们的执行时间有了明显的优化,通过这道题我们也可以明显感觉到 哈希表 对我们程序的优化。
在可能的情况下,应该用 哈希表 来替代多重循环。
看到题目不能只想着解出来了就可以了,要多想想更好的解法。
如果有更好的方法欢迎在下面留言。
也可以去官网去查询官方的详细解答。