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

题目:

输入一个正数s,打印出所有和为s的连续正数序列(至少含有两个数)。例如输入15,由于1+2+3+4+5=4+5+6=7+8=15,所以结果打印出3个连续序列1~5、4~6和7~8。
样例
输入:15
输出:[[1,2,3,4,5],[4,5,6],[7,8]]

解答:

数学公式法:由于是等差数列,假设数列第一个和最后一个数字分别为i和j,则有方程 (i + j)/2 * (j - i + 1) = sum(等式1),可求得 j * (j + 1) = 2* sum + i ^ 2 - i (等式2)。对于每个 i,判断是否存在整数 j符合等式2,若存在则有数列 [i, …, j]的和为sum。由于实际上只需要判断 sum/2 个 i,所以时间复杂度为 O(n)。

class Solution(object):
    def findContinuousSequence(self, sum):
        """
        :type sum: int
        :rtype: List[List[int]]
        """
        rlist = []
        for i in range(1, int(sum/2) + 1):
            right = 2*sum + i**2 - i
            if right >= 0:
                j = int(right**(1/2))
                if j * (j + 1) == right:
                    rlist.append([k for k in range(i, j + 1)])
        return rlist

双指针法:参考剑指Offer,时间复杂度也是O(n)

class Solution(object):
    def findContinuousSequence(self, sum):
        """
        :type sum: int
        :rtype: List[List[int]]
        """
        small, big = 1, 2
        rlist = []
        s = small + big
        while(big <= int(sum/2) + 1):
            if s == sum:
                rlist.append([i for i in range(small, big + 1)])
                s += big + 1
                big += 1
            else:
                if s > sum:
                    s -= small
                    small += 1
                else:
                    s += big + 1
                    big += 1
        return rlist

你可能感兴趣的:(剑指Offer 和为S的连续正数序列)