JZ41 和为S的连续正数序列

描述

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

官方题解:因为是一个连续的正数序列,关于如何求它们的和,其实有一个数学求和公式大家都比较熟悉,就是首项加末项的和乘项数除以2。

假设首项为 i ,末项为  ,即:sum = \frac{(i+j)\times (j-i+1)}{2}

而在这道题目中,关于sum我们已经知道了。

所以只要确定 i 或 j 的值,就能找到另外一个值。

当首项i的值确定时,j = \frac{-1\pm \sqrt{1+4(2\times sum + i^2 -i)}}{2},又因为j>i,所以可以去掉为负数的解。

通过从小到大遍历左边界 i 来计算 以 i 为起始数字的连续正整数序列 。每轮中,由以上公式计算得到右边界 j ,当 j 满足以下两个条件时记录结果:
① j 为 整数 :符合题目所求「连续正整数序列
② i < j :满足题目要求「至少含有两个数

class Solution:
    def FindContinuousSequence(self, tsum):
        # write code here
        i, j, res = 1, 2, []
        while i < j:
            j = (-1 + (1 + 4 * (2 * tsum + i * i - i)) ** 0.5) / 2
            if i < j and j == int(j):
                res.append(list(range(i, int(j) + 1)))
            i += 1
        return res

时间复杂度 O(N): 其中 N =sum;连续整数序列至少有两个数字,而 i < j恒成立,因此至多循环 sum/2 次,使用 O(N)。
空间复杂度 O(1): 变量 i, j 使用常数大小的额外空间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值