剑指offer 57:和为S的两个数字

题目描述:

输入一个递增排序的数组array和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,返回任意一组即可,如果无法找出这样的数字,返回一个空数组即可。

数据范围:

0<=len(array)<=105

1<=array[i]<=106

示例1:

输入:[1,2,4,7,11,15],15

返回值:[4,11]

说明:返回[4,11]或者[11,4]都是可以的

示例2:

输入:[1,5,11],10

返回值:[]

说明:不存在,返回空数组

 示例3:

输入:[1,2,3,4],5

返回值:[1,4]

说明:返回[1,4],[4,1],[2,3],[3,2]都是可以的

解法一:双指针逼近法

思路:由题目可知:该数组是有序递增数组,因此可以利用两个指针 left 和 right,left 指向数组首元素的下标,right 指向数组末元素的下标。遍历数组,判断当前 array[left] 和 array[right] 的和。如果 array[left] 和 array[right] 的和大于 sum ,则 right--。

如果 array[left] 和 array[right] 的和小于 sum ,则 left ++;

如果 array[left] 和 array[right] 的和等于 sum ,则 找到结果,退出循环。

以示例1为例,如下图:

代码如下:

import java.util.*;
public class Solution {
    public ArrayList<Integer> FindNumbersWithSum(int [] array,int sum) {
        //存储结果
        ArrayList<Integer> list = new ArrayList<>();
        //双指针
        int left = 0, right = array.length-1;
        while(left < right){
            //如果array[left]和array[right]的和小于sum,则left++
            if(array[left] + array[right] <  sum){
                left ++;
            }else if(array[left] + array[right] >  sum){//如果array[left]和array[right]的和大于sum,则right--
                right --;
            }else{    //如果array[left]和array[right]的和等于sum,找到结果,直接跳出循环
                list.add(array[left]);
                list.add(array[right]);
                break;
            }
        }
        return list;
    }
}

解法二:HashMap。

思路:利用HashMap存放元素和下标,然后开始遍历数组找到和为sum的两个元素,从左到右找到的第一对和为sum的就是最小的一对。

以示例一为例:

 

 

代码如下: 

import java.util.*;
public class Solution {
    public ArrayList<Integer> FindNumbersWithSum(int [] array,int sum) {
       ArrayList<Integer> list = new ArrayList<>();
        Map<Integer, Integer> map = new HashMap<>();
        //将数组中的元素存入map,key为array[i],value为当前元素的下标
        for(int i=0; i < array.length; i++){
            map.put(array[i], i);
        }
        //遍历数组
        for(int i=0; i < array.length; i++){
            //得到sum-array[i]的值,判断val是否存在于map中
            int val = sum - array[i];
            //如果存在,则找到和为sum的值
            if(map.containsKey(val)){
                list.add(array[i]);
                list.add(val);
                break;
            }
        }
        //返回结果
        return list;
    }
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值