剑指offer:Python 和为S的连续正数序列 图解 和为s的连续正数序列

题目描述

小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列? Good Luck!

输出描述:
输出所有和为S的连续正数序列。序列内按照从小至大的顺序,序列间按照开始数字从小到大的顺序

思路及Python实现

  • 第一种方法:暴力求解,在连续的正数序列中,如果一个数比和的一半要大的话,例如:和为100,如果其中一个数是51,那么,不存在51和另一个连续的数和等于100的这个序列。因此,我们可以借助两个循环,来循环遍历所有和等于tsum的序列!(效率低)

暴力求解

class Solution:
    def FindContinuousSequence(self, tsum):
        res = []
        for i in range(1, tsum // 2 + 1):
            sum = 0
            for j in range(i, tsum // 2 + 2):
                sum += j
                if sum == tsum:
                    res.append(list(range(i, j + 1)))
                if sum > tsum:
                    break
        return res


obj = Solution()
print(obj.FindContinuousSequence(100))

双指针 滑动窗口

  • 利用一个双指针来实现一个滑动窗口,如下图:左侧指针small,右侧指针big;如果当前窗口内的和等于tsum,返回窗口内的所有数,并且移动窗口,窗口右侧向右移动一位或者左侧右移一位都行;
  • 两枚指针之间的和,如果小于tsum的话,窗口的big指针向右移动一位,然后再加上指针移动后指向位置的值;如果大于tsum的话,两枚指针之间的和先减去当前指针指向的值,窗口的samll指针向右移动一位;循环终止条件是,窗口左侧,即(窗口左侧)序列的最小值大于tsum//2,即思路1中的不会有数大于和的一半
  • 详细如下图解
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
class Solution:
    def FindContinuousSequence(self, tsum):
        if tsum == 1:
            return []
        small = 1
        big = 2
        mid = tsum // 2
        cur_sum = big + small  # 会不断更新当前序列的和
        ret = []
        while small <= mid:
            if cur_sum == tsum:
                ret.append(list(range(small, big + 1)))
                big += 1  # 如果右侧窗口移动(先移动再加)
                cur_sum += big  # 不断更新和
            elif cur_sum < tsum:
                big += 1
                cur_sum += big
            else:  # 如果左侧窗口移动(先减在移动)
                cur_sum -= small
                small += 1
        return ret


obj = Solution()
print(obj.FindContinuousSequence(100))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值