示例:
给定 nums = [2, 7, 11, 15], target = 9 因为 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1]
在刚看到这道题时,我首先想到的就是暴力破解法,即把整个数组遍历一遍,找出两个数之和为target的数,将其放在数组中,返回就可以了。但是除了暴力破解法,我们还可以用哈希表来完成这道题目。
解法一:暴力破解法
class Solution {
public int[] twoSum(int[] nums, int target) {
int len = nums.length;
int[] result = new int[2];
for(int i = 0; i < len; i++){
for(int j = i+1; j < len; j++){
if(nums[i] + nums[j] == target){
result[0] = i;
result[1] = j;
return result;
}
}
}
return result;
}
}
复杂度分析:
- 时间复杂度:O(n^2)
- 空间复杂度:O(1)
解法二:两遍哈希表
为了对时间复杂度进行优化,我们需要一种更为有效的方法来检查数组中是否存在目标元素。如果存在,我们需要找出它的索引。保持数组中的每个元素与其索引相互对应的最好方法是什么?哈希表。
通过以空间换取时间的方式,我们可以将查找时间从O(n)降低到O(1)。
我们可以循环两次。在第一次循环中,将每个元素的值和它的索引添加到表中。在第二次循环中,检查每个元素对应的目标元素(target-nums[i])是否存在于表中。注意:该目标元素不可以是nums[i]本身。
public int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
map.put(nums[i], i);
}
for (int i = 0; i < nums.length; i++) {
int complement = target - nums[i];
if (map.containsKey(complement) && map.get(complement) != i) {
return new int[] { i, map.get(complement) };
}
}
throw new IllegalArgumentException("No two sum solution");
}
复杂度分析:
- 时间复杂度:O(n)
- 空间复杂度:O(n)
解法三:一遍哈希表
实际上,我们可以只遍历一次哈希表就可以找到结果。在进行哈希表的插入的同时,查找是否存在(target-nums[i])的数。
public int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
int complement = target - nums[i];
if (map.containsKey(complement)) {
return new int[] { map.get(complement), i };
}
map.put(nums[i], i);
}
throw new IllegalArgumentException("No two sum solution");
}
复杂度分析:
- 时间复杂度:O(n)
- 空间复杂度:O(n)