一、题目描述
输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多对数字的和等于s,则输出任意一对即可。
示例 1:
输入:nums = [2,7,11,15], target = 9
输出:[2,7] 或者 [7,2]
示例 2:
输入:nums = [10,26,30,31,47,60], target = 40
输出:[10,30] 或者 [30,10]
二、思路分析
1、题目中说到是递增数组,即可设置左右两个指针,初始状态分别指向数组的开始元素和结尾元素。
2、当两个指针所指元素小于目标值时,说明左指针该后移了,因为后移后左指针指向的值就比之前大,左右指针指的值之和会比之前大。此时右指针不能动,因为它左边的值都比它小。
3、同理当两个指针指的值之和大于目标值,此时右指针需要左移,因为它左边的值比现在的值要小,只有这样才能让两指针指向的值之和变小。此时左指针不能动,因为左指针右边的值都比它大。
4、这里需要考虑,当左指针右移时,会丢失一组解,就是左指针之前指的值与它之后的在右指针指的值之前的值的组合。
即如果左指针为left,右指针为right,左指针后移会丢失掉以下的解:
{(nums[left],nums[left+1]),(nums[left],nums[left+2])…(nums[left],nums[right-1])}
思考一下,此处左指针后移是因为nums[left]+nums[right]<target,而数组是递增数组,所以以上的解肯定都比nums[left]+nums[right]小,一定不会等于target,所以这些解可以放心丢啦~~
右指针左移同理~~~~
所以我们可以放心按照前三条的思路写代码啦~~
三、代码
1、代码里没有用一个数组直接存储两个结果值是为了节省空间.
2、开始我用了ArrayList想存储结果值,但是ArrayList是不能直接用toArray(T[],a)(T[]指的是数组类型,a是要在其中存储列表元素的数组)返回基本的int[],所以就没用这个了,想用的话只能通过新建一个数组循环赋值或者用IntStream方法。
class Solution {
public int[] twoSum(int[] nums, int target) {
int len=nums.length;
int left=0;
int right=len-1;
// int[] list=new int[2];
while(left<right){
int sum=nums[left]+nums[right];
if(sum<target){
left++;}
else if(sum>target){right--;}
else {
// list[0]=nums[left];
// list[1]=nums[right];
// Integer[] b = new Integer[list.size()];//当泛型为Integer时,需要
// b = (Integer[])list.toArray(b); //以Integer类来作为数组基本元素
// return list;
return new int[]{nums[left],nums[right]};
}
}return new int[0];
}
完毕,撒花花~~