剑指offer - 41和为S的连续正数序列

题目描述

找出所有和为S的连续正数序列,序列内按照从小到大顺序,序列间按照开始数字从小到大

有三种思路:

1. 暴力求解

2. 连续整数序列 是公差为1的等差数列 和为S 长度为N 的中间值为S/N

    N为奇数时,中间值正好是平均值 条件为 i % 2 == 1 && sum % i == 0

    N为偶数时,中间两个数的平均值是序列的平均值 条件为 i % 2 == 0 && (sum % i) * 2 == i

3. 滑动窗口的思想

代码如下:

class Solution {
public:
    //方法一:暴力求解
    vector<vector<int> > find_sequence_common(int sum){
        vector<vector<int> > result;
        for(int i = 1; i < sum;  i++){
            int index  = i;
            int tmpsum = sum;
            vector<int> sequence;
            while(tmpsum > 0){
                sequence.push_back(index);
                tmpsum -= index++;
            }
            if(0 == tmpsum){
                result.push_back(sequence);
            }
        }
        return result;
    }
    //方法二:求平均值  连续整数序列 是公差为1的等差数列 和为S 长度为N 的中间值为S/N
    //      N为奇数时,中间值正好是平均值 条件为 i % 2 == 1 && sum % i == 0
    //      N为偶数时,中间两个数的平均值是序列的平均值 条件为 i % 2 == 0 && (sum % i) * 2 == i
    vector<vector<int> > find_sequence_average(int sum){
        vector<vector<int> > result;
        for(int i = sqrt(sum*2); i >= 2 ; i--){
            if((i % 2 == 1 && sum % i == 0) ||
               (i % 2 == 0 && (sum % i) * 2 == i)){
                cout << i << endl;
                vector<int> sequence;
                for(int k = 0, j = sum / i - (i-1)/2; j > 0 && k < i; k++, j++){
                    sequence.push_back(j);
                }
                result.push_back(sequence);
            }
        }
        return result;
    }
    //方法三:滑动窗口的思想 设两个指针
    //       当和小于sum时 right++
    //       当和大于sum时 left++
    vector<vector<int> > find_sequence_slide_window(int sum){
        vector<vector<int> > result;
        int left  = 1;
        int right = 2;
        while(right > left){
            int temp = (left + right) * (right - left + 1) / 2;
            if(temp < sum){
                right++;
            }
            else if(temp > sum){
                left++;
            }
            else{
                vector<int> sequence;
                for(int i = left; i <= right; i++){
                    sequence.push_back(i);
                }
                result.push_back(sequence);
                left++;
            }
        }
        return result;
    }

    vector<vector<int> > FindContinuousSequence(int sum) {
        //return find_sequence_common(sum);
        //return find_sequence_slide_window(sum);
        return find_sequence_average(sum);
    }
};

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值