剑指Offer57-和为s的连续正数序列-easy

试题链接

题目描述:

输入一个正整数 target ,输出所有和为 target 的连续正整数序列(至少含有两个数)。

序列内的数字由小到大排列,不同序列按照首个数字从小到大排列。

例如输入:

输入:target = 9
输出:[[2,3,4],[4,5]]

输入:target = 15
输出:[[1,2,3,4,5],[4,5,6],[7,8]]

数据范围:
1 <= target <= 10^5
解题思路:

尺取法:顾名思义,像尺子一样取一段,借用挑战书上面的话说,尺取法通常是对数组保存一对下标,即所选取的区
间的左右端点,然后根据实际情况不断地推进区间左右端点以得出答案。之所以需要掌握这个技巧,是因为尺取法比
直接暴力枚举区间效率高很多,尤其是数据量大的。
但是尺取法有他的适用情况

  • 要求一个连续区间
  • 有一个总的标准,比如说,连续区间求和满足一个值sum,求一个连续区间内的xx种类
  • 区间长度是弹性的,在满足标准的情况下,推进左右端点,使得区间长度符合要求.

回过头看此题是否满足尺取法的要求呢

  • 连续的正整数序列
  • 标准:正整数序列和满足 target
  • 区间长度是弹性的
    Yes! 满足要求,接下来看算法的流程
    算法流程:
  • 初始化三个变量 i = 1 表示头指针, j = 2 表示尾指针,sum = 1和一个动态数组(vector)tmp.
  • 进入循环
    • 如果 i < j (头指针小于尾指针) 且 sum < target (求和不等于target的值)循环执行
      • sum += j (sum加上尾指针的值)
      • tmp加入j (序列加上尾指针的值)
      • j+=1 (尾指针后移一位)
    • 如果i >=j(头指针大于等于尾指针)
      结束整个循环
    • 如果 sum 等于 target
      • 判断此时tmp的大小,满足大于等于2的话,最后结果集加入此序列
      • tmp删除头指针的值
      • sum-=头指针的值
      • 头指针后移一位
        总的来说,就像一条毛毛虫
        演示一下题目给的用例。
        在这里插入图片描述
        在这里插入图片描述
        在这里插入图片描述
        在这里插入图片描述
AC代码(c++)
class Solution {
public:
    vector<vector<int> > findContinuousSequence(int target) {
        vector<vector<int> > arr;
        vector<int> tmp;
        int i=1,j=2;
        int sum = 1;
        tmp.push_back(1);
        while(1){
            while(i<j && sum<target){
                sum+=j;
                tmp.push_back(j);
                j++;
            
            }
            if(i>=j)
                break;
            if(sum==target)
            {
                if(tmp.size()>=2){
                    arr.push_back(tmp);
                }
                tmp.erase(tmp.begin());
                sum-=i;
                i++;
            }
            while(sum>target){
                sum-=i;
                i++;
                tmp.erase(tmp.begin());
            }
        }
        return arr;
       
    }
};

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值