Two sum
indices,index的复数形式
题目
给定一个整数数组,返回两个数字索引,使其相加等于特定值。
假定每次输入只有一个确定解,并且不能重复使用相同元素。
示例:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
Solution
思路一:暴力求解
对每一个元素x
,查找是否存在target - x
.
public int[] twoSum(int[] nums, int target) {
for (int i = 0; i < nums.length; i++) {
for (int j = i + 1; j < nums.length; j++){
if (nums[j] == target - nums[i]) {
return new int[] { i, j};
}
}
}
throw new IllegalArgumentException("No two sum solution");
}
复杂度分析
- 时间复杂度:\(O(n^2)\).
- 空间复杂度:\(O(1)\).
思路二:两遍哈希表
为了改进时间复杂度,需要更有效的方式检测数组里补数是否存在。如果补数存在,我们需要查找它的索引。维持元素和索引之间映射最有效的方式就是哈希表。
通过用空间换取速度,将查找时间由\(O(n)\)减至\(O(1)\)。哈希表可以完成这个目的。
简单实现为两个迭代。
- 添加元素值和索引到哈希表。
- 检测元素补数是否存在
target - 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)\).
一遍哈希表
一遍插入元素,一边往回检测哈希表中是否已经存在当前元素的补数。
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(num[i], i);
}
throw new IllegalArguementException("No two sum solution");
}
复杂度分析
- 时间复杂度:\(O(n)\).
- 空间复杂度:\(O(n)\).