Python实现数据结构与算法——和为s的连续正数序列

旧街凉风 提交于 2020-03-07 18:39:29

题目描述:

输入一个正整数 target ,输出所有和为 target 的连续正整数序列(至少含有两个数)。

序列内的数字由小到大排列,不同序列按照首个数字从小到大排列。

示例1:
输入:target = 9
输出:[[2,3,4],[4,5]]
示例2:
输入:target = 15
输出:[[1,2,3,4,5],[4,5,6],[7,8]]
限制:
1 <= target <= 10^5

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/he-wei-sde-lian-xu-zheng-shu-xu-lie-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路:

  1. 连续正数序列的最大值不会超过target/2
  2. 等差序列求和公式,可以求得首末尾正数的关系,记作x和y
  3. 从1到int(target/2)遍历x,找出满足使y为整数的x,即x和y为序列的首尾数。代码如下:
import math

class Solution:
    def findContinuousSequence(self, target: int):
        result = []
        for i in range(int(target/2)):
            q = 1 - 4 * (-(i+1)**2+(i+1)-2*target)
            x1 = (-1 + math.sqrt(q)) / 1 / 2
            x2 = (-1 - math.sqrt(q)) / 1 / 2
            x = max(x1,x2)
            if not (x-int(x)):
                result.append([j for j in range((i+1),int(x+1))])
        return result

测试结果:
在这里插入图片描述另一种思路:

  1. 如果满足条件的正整数序列里正整数的个数为n,那么如果n为奇数,则平均值target/n为整数,如果n为偶数,则平均值小数点后为0.5。所以遍历个数。
  2. 当均值满足条件时,前后n个数即为所求数列。
  3. 根据公式(2a+n)n=target,且a>0,则可以求得n<(2target)**0.5
    代码如下:
class Solution:
    def findContinuousSequence(self, target: int):
        result = []
        for n in range(int((2*target) ** 0.5),1,-1):
            i = target/n
            if i-n//2 > 0:
                if i%1 == 0 and n & 1:
                    result.append([j for j in range(int(i-n//2), int(i+n//2+1))])
                elif i%1 == 0.5 and not n & 1:
                    result.append([j for j in range(int(i-n//2+1), int(i+n//2+1))])
        return result

测试结果:
在这里插入图片描述

总结:

数学题用数学方法解答总是快的,可以避免不必要的遍历。官方题解中,有一个双指针的方法,感兴趣的可以去看看。
题解链接:

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!