剑指offer42 和为s的两个数字


剑指offer42

和为s的两个数字

题目描述

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

输入

[1,2,4,7,11,15],15

输出

[4,11]

思路

不要被题目误导了!证明如下,清晰明了:

//输出两个数的乘积最小的。这句话的理解?

假设:若b>a,且存在,

a + b = s;

(a - m ) + (b + m) = s

则:(a - m )(b + m)=ab - (b-a)m - m*m < ab;说明外层的乘积更小

也就是说依然是左右夹逼法!!!只需要2个指针

1.left开头,right指向结尾
2.如果和小于sum,说明太小了,left右移寻找更大的数
3.如果和大于sum,说明太大了,right左移寻找更小的数
4.和相等,把left和right的数返回

代码

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

总结

很多题目都是给定一个数组,要求返回两个下标的(比如找两个元素,或者找一个子数组)。相应比较高效的解法,则是先排序,然后在一个循环体里利用两个变量进行反向的遍历,并且这两个变量遍历的方向是不变的,从而保证算法时间复杂度为 O(N)。这样类似的问题,可以考虑用双下标进行遍历


文章作者: Hailong Gao
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Hailong Gao !
评论
  目录