问题描述
小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列?
输出描述:
输出所有和为S的连续正数序列。序列内按照从小至大的顺序,序列间按照开始数字从小到大的顺序
解题思路
根据题意,每个整数序列符合下列形式:
[ a,a+1,a+2, … , a+k ]
记所给正数为T.
根据等差数列求和公式:
(k+1)(k+2*a) = 2 T
根据题意要求, K>=1.
则可以计算出所有 2 T 的因式分解情况,
从2计算到
2T−−−√
2
T
即可
以 T=100 为例:
[2,50] ,[4,25],[5,20],[10,10]
遍历这些数组, 由于 a > 0 ,所以 k+1 < k + 2*a,
所以对于每一个因子组合,记为 [m1,m2]
取 m1 = k + 1 , 当 (m2 - k ) mod 2 = 0 时,即为一组所求序列。
遍历这些因子组合后即可得到所有所求序列。
编程实现(python2)
class Solution:
def FindContinuousSequence(self, tsum):
# write code here
def get_mul_pair(tsum):
'''
辅助函数,计算tsum的所有乘积因子对
'''
if tsum == 1:
return [1]
res = []
c=2
while c**2 <= tsum:
if tsum % c == 0:
res.append([c,tsum/c])
c += 1
return res
def get_continue_list(a,k):
'''
辅助函数,
输出 [a,a+1,...,a+k]
'''
res=[]
for i in range(k+1):
res.append(a+i)
return res
mul_list = get_mul_pair(2*tsum)
res = []
for pair in mul_list:
if pair[1]>pair[0] and (pair[1]-(pair[0]-1))%2 == 0:
res.append(get_continue_list((pair[1]-(pair[0]-1))/2,pair[0]-1))
return res[::-1]
测试样例
输入:
S=Solution()
print (S.FindContinuousSequence(100))
输出
[[9, 10, 11, 12, 13, 14, 15, 16], [18, 19, 20, 21, 22]]
输入:
S=Solution()
print (S.FindContinuousSequence(9))
输出
[[2, 3, 4], [4, 5]]
输入:
S=Solution()
print (S.FindContinuousSequence(101))
输出
[[50, 51]]