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

剑指offer57-Ⅱ

题意

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

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

 

注意:结果要是 连续的正整数序列 。所以,示例1中,返回的结果不能有 [1,8]、[2,7]....等,因为这些不是连续的序列。

解题思路—滑动窗口

        对于这道题来说,数组就是正整数序列 [1,2,3,…,n]。我们设滑动窗口的左边界为 i,右边界为 j,则滑动窗口框起来的是一个左闭右开区间 [i, j)。

        为了编程的方便,滑动窗口一般表示成一个左闭右开区间。在一开始,i=1, j=1,滑动窗口位于序列的最左侧,窗口大小为零。

 

        在这道题中,我们关注的是滑动窗口中所有数的和。当滑动窗口的右边界向右移动时,也就是 j = j + 1,窗口中多了一个数字 j,窗口的和也就要加上 j。当滑动窗口的左边界向右移动时,也就是 i = i + 1,窗口中少了一个数字 i,窗口的和也就要减去 i。滑动窗口只有 右边界向右移动(扩大窗口) 和 左边界向右移动(缩小窗口) 两个操作,所以实际上非常简单。

C++实现

class Solution 
{
public:
    vector<vector<int>> findContinuousSequence(int target) 
    {
        // i和j是滑动窗口的左右边界( [i,j) )
        int i=1,j=1;
        //滑动窗口内的和
        int sum=0;
        vector<vector<int>>res; //最终结果
           
        //滑动窗口左边界最多只能到target的一半,因为再大的话,滑动窗口内的和就会超过target。
        while(i<=(target/2))    
        {
            //滑动窗口内的和大于target了,左边界就要向右移动,缩小窗口
            if(sum>target)
            {
                sum-=i;
                i++;
            }
            //滑动窗口内的和小于target了,右边界就要向右移动,增大窗口
            else if(sum<target)
            {
                sum+=j;
                j++;
            }
            //滑动窗口内的和等于target了,记录结果。并且左边界向右移动,
            //看以下一个序列开头的窗口内的和能否等于target。
            else
            {
                vector<int>tmp;
                for(int k=i;k<j;k++)
                {
                    tmp.emplace_back(k);
                }
                res.emplace_back(tmp);
                sum-=i;
                i++;
            }
        }
        return res;
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

心之所向便是光v

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值