题目描述:
输入一个正整数 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
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路:
- 连续正数序列的最大值不会超过target/2
- 等差序列求和公式,可以求得首末尾正数的关系,记作x和y
- 从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
测试结果:
另一种思路:
- 如果满足条件的正整数序列里正整数的个数为n,那么如果n为奇数,则平均值target/n为整数,如果n为偶数,则平均值小数点后为0.5。所以遍历个数。
- 当均值满足条件时,前后n个数即为所求数列。
- 根据公式(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
测试结果:
总结:
数学题用数学方法解答总是快的,可以避免不必要的遍历。官方题解中,有一个双指针的方法,感兴趣的可以去看看。
题解链接:
来源:CSDN
作者:Mantana
链接:https://blog.csdn.net/Mantana/article/details/104694552