第 57-2 题:和为 S 的连续正数序列
传送门:AcWing:和为 S 的连续正数序列。
输入一个正数 s ,打印出所有和为 s 的连续正数序列(至少含有两个数)。
例如输入
,由于
,所以结果打印出
个连续序列
、
和
。
样例:
输入:
输出:
思路:双指针,因为是有序数组,所以可以使用二分法。
设定两个指针,一个指向第一个数,一个指向最后一个数,在此之前需要设定第一个数和最后一个数的值,由于是正数序列,所以可以把第一个数设为 ,最后一个数为
,因为是要求是连续正数序列,最后不可能和第一个数重合。下一步就是不断改变第一个数和最后一个数的值,如果从第一个数到最后一个数的和刚好是要求的和,那么把所有的数都添加到一个序列中;如果大于要求的和,则说明从第一个数到最后一个数之间的范围太大,因此减小范围,需要把第一个数的值加
,同时把当前和减去原来的第一个数的值;如果小于要求的和,说明范围太小,因此把最后一个数加
,同时把当前的和加上改变之后的最后一个数的值。这样,不断修改第一个数和最后一个数的值,就能确定所有连续正数序列的和等于
的序列了。
等差数列求和公式,首项加末项的和乘以个数除以 ,即
。
注意:右边界问题,使用一个特例,例如 就可以考虑清楚了。
Python 代码:
class Solution(object):
def findContinuousSequence(self, sum):
"""
:type sum: int
:rtype: List[List[int]]
"""
res = []
left = 1
right = 2
# sum = 3 的时候,右边界最多到 2
half = sum // 2 + 1
while left < right <= half:
cur_sum = (left + right) * (right - left + 1) // 2
if cur_sum == sum:
res.append([i for i in range(left, right + 1)])
right += 1
elif cur_sum < sum:
right += 1
else:
assert cur_sum > sum
left += 1
return res
if __name__ == '__main__':
sum = 15
solution = Solution()
result = solution.findContinuousSequence(sum)
print(result)