和为S的两个数字

题目:

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

思考:

递增排序,从左往右数逐渐增大,而且不会出现重复的数字。当有多对数字和等于S的时候,如何选出乘积最小的那个呢?

说明一种情况,设有两个数x, y。

若x为矩形的长,y为矩形的宽。当x + y 为定值时,怎么样才能使矩形的面积最大呢?

相信大家都知道是当矩形的长和宽相等的时候,矩形的面积最大。此时,矩形的面积为xy,就是这两个数的乘积。

那么,考虑极限情况,当x 和 y 中的某一个数字为0时,x 和 y的乘积最小。

可以推广开来得到,当x + y为定值时,|x - y| 的值越小,x 和 y 的乘积越大;|x - y| 的值越大,x 和 y 的乘积越小。———结论1

(推理的过程不是十分的严谨,不过结论是这样的。用数学方法解决,就是另x + y = z; x * y = x * (z - x)  = - x^{2} + xz 配方之后得到

x * y = -(x - \frac{z}{2})^{2} + \frac{z^{2}}{4} 画出曲线,就可以知道矩形面积的变化规律,就是上述所提到的结论1)

从最左边的一个数字开始,与最右边的数字相加,如果相加的数大于所要得到的和,那么继续与次右边的数相加。如果相加得到的数小于所要得到的和,就不在考虑左边这个数字与其他数字的结合了。因为,左边这个数字再与右侧更小的数字结合,也不可能得到符合条件的数字。依次对每一个左侧的数进行这样的操作,当找到符合条件的时,退出循环,返回结果。

class Solution {
public:
    vector<int> FindNumbersWithSum(vector<int> array,int sum) {
        int len = array.size();
        vector<int> solve;
        if(len < 2) return solve;
        int left = 0;
        int right = len - 1;
        int flag = 1;
        while(flag && left < right) {
            int i = 0;
            while(i < right - left) {
                if(array[left] + array[right - i] == sum) {
                    solve.push_back(array[left]);
                    solve.push_back(array[right - i]);
                    flag = 0;
                    break;
                }
                else if(array[left] + array[right - i] > sum){
                    i++;
                }
                else {
                    break;
                }
            }
            left++;
        }
        return solve;
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值