剑指Offer系列之57:和为s的两个数字(超简单双指针解法)

一、题目描述

输入一个递增排序的数组和一个数字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]; 
           
    }

完毕,撒花花~~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值