剑指offer41-和为S的连续正数序列

题目描述

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

返回值描述:

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

知识点回顾

穷举

代码

i表示连续的正数序列的元素个数,最少为2个,所以初始化为2.

当tsum<3时,不存在这样的序列。

循环条件: n*(n-1)/2<=tsum

当i是偶数时,序列满足两两结对和=tsum/(i/2), 且位于最中间的两个元素和满足:

    a+b=tsum/(i/2)

    b-a=1

所以i为偶数时条件:tsum%(i//2)==0 and (tsum//(i//2))%2==1,由序列连续可以推出序列第j个元素为 j+(tsum//(i/2)-1)//2-(i/2-1),j=0,1,...,i.

i为奇数时,位于最中间的元素等于序列均值,因此条件为:tsum%i==0,推出序列第j个元素为 j+(tsum//i)-(i-1)/2,j=0,1,...,i.

# -*- coding:utf-8 -*-
class Solution:
    def FindContinuousSequence(self, tsum):
        # write code here
        a,b=[],[]
        if tsum<3:
            return a
        i=2
        while (i+i**2)<=2*tsum:
            a=[]
            if i%2==0:
                if tsum%(i//2)==0 and (tsum//(i//2))%2==1:
                    for j in range(i):
                        a.append(j+(tsum//(i/2)-1)//2-(i/2-1))
            else:
                if tsum%i==0:
                    for j in range(i):
                        a.append(j+(tsum//i)-(i-1)/2)
            i+=1
            if a:
                b.append(a)
        b.reverse()
        return b

 

posted @ 2020-12-05 17:10  foolangirl  阅读(50)  评论(0编辑  收藏  举报