剑指offer42_和为s的两个数

题目描述

输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。

输出描述:对应每个测试案例,输出两个数,小的先输出。

题解一 map

使用map。比如 [1,3,4,11],sum为15。

​ 第一个数为1,15-1=14,需要寻找到值为14这个数,如果有则[1,14]可能是答案。但是map.get(14)不存在,所以将key = 1,value = 14加到map中

1
14

​ 同理,第二个数为3,15-3=12,需要寻找到值为12这个数,如果有则[3,12]可能是答案。但是map.get(12)不存在,所以将key = 3, value = 12加到map中

13
1412

​ [4,11]同理。

134
141211

​ 到了第四个数为11的时候,15 - 11 = 4,这个时候map.get(4)的值为11,那么[11,4]有可能是答案,先将乘积44记下来。这个时候数组已经遍历完毕,所以答案就是[4,11]。

13411
1412114

Java代码

import java.util.ArrayList;
import java.util.HashMap;
public class Solution {
    public ArrayList<Integer> FindNumbersWithSum(int [] array,int sum) {
        HashMap<Integer,Integer> map = new HashMap<>();
        ArrayList<Integer> list = new ArrayList<>();
        int plus = 0;
        //遍历数组
        for(int i = 0; i < array.length; i++){
            if(array[i] <= sum){
                int other = sum - array[i];
                //map的key对应array[i],value对应other
                if(map.get(other) != null){
                    if(list.size() == 0){
                        list.add(other);
                        list.add(array[i]);
                    }else{
                        if(list.get(0) * list.get(1) >= other * array[i]){
                            list.clear();
                            list.add(other);
                            list.add(array[i]);
                        }
                    }
                }
                else {
                    map.put(array[i],other);
                }
            }else break; //因为这是递增排序的数组,如果array[i]大于sum,直接跳出循环
        }
        return list;
    }
}

题解二 双指针

用一个头指针指向数组的第一个a,用一个尾指针指向数组的最后一个b,如果a大于sum,或者a+b > sum,那么尾指针向前移动。如果a + b < sum,那么头指针向前移动。题目要求的是求出和为sum的数如果有多对,返回乘积最小的一对,返回第一对和为sum的数就可以了。记住这是一个递增的数组,最初求出的结果就是符合题目的。

比如:a + b = sum

(a+1)*(b-1) = ab + b - a - 1

a*b = ab

只要b-a >= 1就可以证明第一个对就是题目所要求乘积最小的结果。

import java.util.ArrayList;
import java.util.HashMap;
public class Solution {
    public ArrayList<Integer> FindNumbersWithSum(int [] array,int sum) {
        int i = 0;
        int j = array.length - 1;
        ArrayList<Integer> list = new ArrayList<>();
        while(i < j){
            if(array[i] + array[j] == sum){
                list.add(array[i]);
                list.add(array[j]);
                return list;
            }
            if(array[j] > sum || array[i] + array[j] > sum) --j;
            if(array[i] + array[j] < sum) ++i;
        }
        return list;
    }
}

如有问题希望指出,谢谢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值