题目
输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多对数字的和等于s,则输出任意一对即可。
分析
先确定一个数,再依次判断数组中剩余的数字与它的和是不是等于s,若等于s则返回这两个数。
代码
public class Solution {
public static void main(String[] args) {
int[] arr = {10,26,30,31,47,60};
int[] arrayList = twoSum(arr,40);
System.out.println(Arrays.toString(arrayList));
}
/**
* 在数组中查找两个数,使得它们的和正好是target。
* @param nums 递增排序的数组
* @param target 两数之和
* @return 数组
*/
public static int[] twoSum(int[] nums, int target) {
int[] arr = new int[2];
for (int i = 0; i < nums.length; i++){
for (int j = i; j < nums.length; j++){
if (nums[i] + nums[j] == target){
arr[0] = nums[i];
arr[1] = nums[j];
}
}
}
return arr;
}
}
分析
本题的 numsnums 是 排序数组 ,因此可使用 双指针法 将空间复杂度降低至 O(1)O(1) 。
算法流程:
初始化: 双指针 ii , jj 分别指向数组 numsnums 的左右两端 (俗称对撞双指针)。
循环搜索: 当双指针相遇时跳出;
计算和 s = nums[i] + nums[j];
若 s > targets ,则指针 j 向左移动,即执行 j = j - 1 ;
若 s < targets ,则指针 i 向右移动,即执行 i = i + 1 ;
若 s = targets ,立即返回数组 [nums[i], nums[j]];
代码
public class Solution {
public static void main(String[] args) {
int[] arr = {10,26,30,31,47,60};
int[] arrayList = twoSum(arr,40);
System.out.println(Arrays.toString(arrayList));
}
/**
* 在数组中查找两个数,使得它们的和正好是target。
* @param nums 递增排序的数组
* @param target 两数之和
* @return 数组
*/
public static int[] twoSum(int[] nums, int target) {
int[] arr = new int[2];
int j = nums.length - 1;//从右向左
int i = 0;//从左向右
while (j > i){
if (nums[i] + nums[j] > target){
j--;
}else if (nums[i] + nums[j] < target){
i++;
}else{
arr[0] = nums[i];
arr[1] = nums[j];
break;
}
}
return arr;
}
}