和为S的数字及进阶

18 篇文章 0 订阅

题目:

在一个递增排序的数组中,找到两个数字和为S,如果有多组,则返回乘积最小的那两个数字。

思路:

排序好的数组。用两个指针p,q分别指向首尾两个数字。如果和小于S,则指针p向右移动一位继续比较。

如果和大于S,则指针q向左移动一位继续比较。
如果相等,则p和q分别向右和左移动一位寻找下一组数字。

class Solution {
public:
    vector<int> FindNumbersWithSum(vector<int> array,int sum) {
        int len = array.size();
        vector<int> res;
        if(len == 0) return res;
        int mult = INT_MAX;
        int p = 0; int q = len -1;
        while(p<q)
        {
            int sum_pq = array[p] + array[q];
            if(sum_pq > sum){
                q--;
            }
            else if(sum_pq < sum){
                p++;
            }
            else{
                int cur = array[p] * array[q];
                if(cur < mult){
                    res.clear();
                    res.push_back(array[p]);
                	res.push_back(array[q]);
                    mult = cur;
                }
                p++;
                q--;
            }
        }
        return res;
    }
};
进一步分析:对于一个和为S的两个数,肯定是两个数之间相差越大越好。所以其实找到的第一组数字就是解。

class Solution {
public:
    vector<int> FindNumbersWithSum(vector<int> array,int sum) {
        int len = array.size();
        vector<int> res;
        if(len == 0) return res;
        int p = 0; int q = len -1;
        while(p<q)
        {
            int sum_pq = array[p] + array[q];
            if(sum_pq > sum){
                q--;
            }
            else if(sum_pq < sum){
                p++;
            }
            else{
                res.push_back(array[p]);
                res.push_back(array[q]);
                break;
            }
        }
        return res;
    }
};

进阶题目:

输入一个正数S,打印出所有和为S的连续正数序列(至少含有两个数)。例如输入15,由于 1+2+3+4+5= 4+5+6=7+8=15,所以有三个序列,均需保存。

思路:

与上题类似,定义两个指针p,q   分别指向当前正数序列的最左端和最右端。q的范围至多到S的一半,q<=(S+1)/ 2,参考S = 5, 序列为 2,3.

用sum_temp保存当前序列之和。如果sum_temp小于S,q向后移动一位。当sum_temp大于S,需要右移p,也要重新计算当前序列之和。为了避免重新累加计算序列和,可以充分利用前面的sum_temp,即用sum_temp - p得到新的sum_temp,之后再更新p为p+1。

class Solution {
public:
    vector<vector<int> > FindContinuousSequence(int sum) {
        vector<vector<int>> res;
        if(sum <= 2) return res;
        vector<int> eachres;
        int i = 1;
        int p = 1;
        int q = 2;
        int sum_temp = p+q;
        while(q <= (sum+1)/2 && p < q){
            if(sum_temp < sum){
                q++;
                sum_temp += q;
            }
            if(sum_temp > sum){
                sum_temp = sum_temp - p;
                p++;
            }
            if(sum_temp == sum){
                eachres = FindOneSolution(p,q);
                res.push_back(eachres);
                eachres.clear();
                sum_temp = sum_temp - p;
                p++;
            }
        }
        return res;
    }
    vector<int> FindOneSolution(int p , int q){
        vector<int> res;
        for(int i = p; i<=q; i++){
            res.push_back(i);
        }
        return res;
    }
};



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值