剑指Offer 和为S的两个数字

寻找最佳匹配对
本文介绍了一种算法,用于在一个递增排序的数组中查找两个数,使它们的和等于给定值S,并确保找到的这对数乘积最小。通过设置头尾两个迭代器并逐步逼近的方式,高效地解决了这一问题。

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

首先做一个证明:
作者:马客(Mark)
链接:https://www.nowcoder.com/questionTerminal/390da4f7a00f44bea7c2f3d19491311b
来源:牛客网

找到的第一组(相差最大的),也就是乘积最小的。可以这样证明:考虑x+y=C(C是常数),xy的大小。不妨设y>=x,y-x=d>=0,即y=x+d, 2x+d=C, x=(C-d)/2, xy=x(x+d)=(C-d)(C+d)/4=(C2-d2)/4,也就是xy是一个关于变量d的二次函数,对称轴是y轴,开口向下。d是>=0的,d越大, xy也就越小。

因此设置头,尾两个迭代器,当找到第一组满足 两个数相加等于S的时候,这两个数也是乘积最小的。
如果两个数的和大于S,那么尾迭代器向头移动,直到等于或小于为止;
同理,如果两个数的和小于S,那么头迭代器向尾移动,直到等于或大于为止;

    vector<int> FindNumbersWithSum(vector<int> array,int sum)
    {
        int i = 0, j = array.size() - 1;
        vector<int> res;
        while(i < j)
        {
            if(array[i] + array[j] == sum)
            {
                res.push_back(array[i]);
                res.push_back(array[j]);
                break;
            }
            while(i<j && array[i] + array[j] > sum)
            {
                j--;
            }
            while(i<j && array[i] + array[j] < sum)
            {
                i++;
            }
        }
        return res;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值