给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。
你可以按任意顺序返回答案。
示例 1:
输入:nums = [2,7,11,15], target = 9 输出:[0,1] 解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
示例 2:
输入:nums = [3,2,4], target = 6 输出:[1,2]
示例 3:
输入:nums = [3,3], target = 6 输出:[0,1]
提示:
2 <= nums.length <= 104-109 <= nums[i] <= 109-109 <= target <= 109- 只会存在一个有效答案
当数组是有序的情况下,可以用双指针
想象两个人,一个从左边开始,一个从右边开始:
回合1:
[2, 7, 11, 15]
↑ ↑
左人 右人
左人拿着 2,右人拿着 15
2 + 15 = 17,太大了!
→ 右人往左走一步(因为右边的数大,所以让右人往左走)
回合2:
[2, 7, 11, 15]
↑ ↑
左人 右人
左人拿着 2,右人拿着 11
2 + 11 = 13,还是太大!
→ 右人再往左走一步
回合3:
[2, 7, 11, 15]
↑ ↑
左人 右人
左人拿着 2,右人拿着 7
2 + 7 = 9,正好!✓
→ 找到答案
class Solution {
public int[] twoSum(int[] numbers, int target) {
int left = 0;
int right = numbers.length - 1;
while (left < right){
int sum = numbers[left]+numbers[right];
if(sum == target){
return new int[]{left,right};
}
else if(sum < target){
left = left + 1;
}
else if (sum > target){
right = right - 1;
}
return new int[]{};
}
}
}
当数组不是有序的情况下就得使用哈希表
普通数组:
位置: 0 1 2 3
值: [2, 7, 11, 15]
↑
要找7,需要从头找到尾 O(n)
哈希表:
键(Key) → 值(Value)
2 → 0 ← 数字2在位置0
7 → 1 ← 数字7在位置1
11 → 2
15 → 3
查找7在哪?直接问哈希表 → O(1) 超快!
问题:找两个数,使得 a + b = target
如果我当前看到数字 a,
那么我需要找的另一个数字是:b = target - a
例如:
target = 9
当前数字 = 2
需要找:9 - 2 = 7
问题变成:前面有没有出现过 7?
边遍历数组,边记录:
"我见过什么数字,它在哪个位置"
当看到新数字时,问哈希表:
"我需要的数字之前见过吗?"
import java.util.HashMap;
public class Solution {
public int[] twoSum(int[] nums, int target) {
// 创建一个哈希表
// Key:数组中的数字
// Value:这个数字的下标
HashMap<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);
}
// 没找到(题目保证有答案,一般不会执行)
return new int[]{};
}
}
浙公网安备 33010602011771号