描述
小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列? Good Luck!
官方题解:因为是一个连续的正数序列,关于如何求它们的和,其实有一个数学求和公式大家都比较熟悉,就是首项加末项的和乘项数除以2。
假设首项为 i ,末项为 ,即:
而在这道题目中,关于sum我们已经知道了。
所以只要确定 i 或 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 使用常数大小的额外空间。