题目
输入一个正整数 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
思路
双指针法
我们用两个指针 ll
和 rr
表示当前枚举到的以 ll
为起点到 rr
的区间,sum
表示 [l,r]
的区间和,由求和公式可 O(1) 求得为 sum=(l+r)*(r-l+1)/2
起始 l=1,r=2l=1,r=2
。
一共有三种情况:
如果 sum<target
则说明指针 rr
还可以向右拓展使得 sum
增大,此时指针 rr
向右移动,即 r+=1
如果 sum>target
则说明以 ll
为起点不存在一个rr
使得 sum=target
,此时要枚举下一个起点,指针ll
向右移动,即l+=1
如果 sum==target
则说明我们找到了以 ll 为起点得合法解 [l,r]
,我们需要将 [l,r]
的序列放进答案数组,且我们知道以ll
为起点的合法解最多只有一个,所以需要枚举下一个起点,指针ll
向右移动,即l+=1
终止条件即为l>=r
的时候
代码
class Solution:
def findContinuousSequence(self, target: int) -> List[List[int]]:
if target < 3:
return []
l, r = 1, 2
ans = []
while(l < r):
s = (l + r) * (r - l + 1) // 2
if s == target:
ans.append([i for i in range(l, r + 1)])
l += 1
s -= l
elif s < target:
r += 1
s += r
else:
l += 1
s -= l
return ans