剑指No.57_和为s的两个数字
- 题目:输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多对数字的和等于s,则输出任意一对即可。
示例:输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多对数字的和等于s,则输出任意一对即可。
- 二分查找+双指针
有一个关键条件就是递增排序的数组,所以马上想到了二分查找,当然本题用与不用二分查找没有太大差别,但希望培养一下这类思维。
public int[] towSumWay(int[] nums, int target){
int low = 0;
int high = nums.length - 1;
while (low < high){
int middle = (low + high) / 2;
if (nums[middle] > target)
high = middle - 1;
else
low = middle + 1;
}
if (nums[low] > target)
low--;
int j = low;
for (int i = 0; i < j;){
if (nums[i] + nums[j] == target)
return new int[]{nums[i], nums[j]};
else if (nums[i] + nums[j] < target)
i++;
else
j--;
}
return null;
}
在数组中当一个元素比target还大,那自然后面的元素都不可能是两个数字之一了(数组中无负数),那么先用二分查找找到最后一个比target小的数字,尽可能缩小数组范围。
然后定义两个指针,一个指向数组末尾,一个指向数组开头,当两个指针上的数字和比target小的时候,那么就说明小数太小,该把数组开头的指针往后移动一位。如果两数之和比target大,那么说明大数太大,该把数组末尾的指针往前移动一位。如果两数之和等于target就返回这两个数。