和为S的连续正数序列

这篇博客探讨了如何找到所有连续正数序列,其和等于给定的目标值S。作者提出了两种解题思路:中位数法和滑动窗口求和公式法,并详细解释了每种方法的原理和实现。通过这些方法,可以有效地找出所有满足条件的序列。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

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

思考

  • 解法一:中位数
    对于符合条件的连续正数序列,他们的中位数就是平均数:
    如果中位数是整数,说明序列长度是奇数;
    如果中位数小数部分是0.5, 说明序列长度是偶数。
    因此,对于给定的序列长度,可以根据中位数来拼接得到整个正数序列。
    当然序列长度是有范围的:
    2 &lt; = l e n g t h &lt; = t s u m 2&lt;= length &lt;= tsum 2<=length<=tsum

  • 解法二:滑动窗口+求和公式
    转自剑指Offer(四十一):和为S的连续正数序列 | Jack Cui
    如果已知序列的首元素和尾元素,那么根据求和公式可以得出:
    s u m = ( h e a d + t a i l ) ∗ ( t a i l − h e a d + 1 ) / 2 sum = (head+tail)*(tail-head+1)/2 sum=(head+tail)(tailhead+1)/2
    计算得到的sum与tsum比较,会有如下三种情况:

  1. sum == tsum, 记录序列[head:tail+1],接着考虑下一个序列,head+=1;
  2. sum < tsum, 将序列范围范围扩大,tail+=1;
  3. sum > tsum, 说明前后两次[tail:head+1]的sum刚好落在tsum两侧,以head为起始的正数序列不满足要求,接着考虑下一个序列。head+=1。

代码

  • 解法一
# -*- coding:utf-8 -*-
class Solution:
    def FindContinuousSequence(self,tsum):
        res = []
        i = tsum
        while i >= 2:
            if i%2 == 0 and divmod(tsum,i)[1] != 0 and divmod(float(tsum)/i*10,5)[1] == 0 and tsum/i-i/2+1 >= 1 :          #偶数个,那么中位数的小数部分必为0.5                                                             
                res.append([x for x in range(int(tsum/i)-i/2+1,int(tsum/i)+i/2+1)])
            if i%2 != 0 and tsum%i == 0 and tsum/i-(i-1)/2 >= 1:                                                           #奇数个,那么中位数必为整数  
                res.append([x for x in range(tsum/i-(i-1)/2,tsum/i+(i+1)/2)])
            i -= 1
        return res
  • 解法二
# -*- coding:utf-8 -*-
class Solution:
    def FindContinuousSequence(self, tsum):
        # write code here
        low, high = 1,2
        res = []
        while low < high:
            sum = (low+high)*(high-low+1)/2
            if sum == tsum:
                res.append([x for x in range(low, high+1)])
                low += 1
            elif sum < tsum:
                high += 1
            else:
                low += 1
        return res
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值