今天我们来做一道LeetCode上的题目,原题链接:剑指 Offer 57 - II. 和为s的连续正数序列
题目描述
- 输入一个正整数 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
思路分析
- 数学公式方法
- 一个以a1为首项,以1为公差,以n为项数的等差数列的和为target
- 公式和:target = na1 + n(n - 1) / 2
- 变换公式:a1 = (target - n(n - 1) / 2) / n
- 目标是找出所有满足条件的n和a1
- 滑动窗口法
- i, j = 1, 2
- cur_sum = sum(list(range(i, j + 1)))
代码
# Python
class Solution(object):
def findContinuousSequence(self, target):
"""
:type target: int
:rtype: List[List[int]]
"""
# # 1. 数学公式等差数列之和
# res = []
# for n in range(2, target):
# temp = target - n*(n-1)//2
# if temp <= 0:
# break
# if not temp % n:
# a_1 = temp // n
# res.append([a_1 + i for i in range(n)])
# return res[::-1]
# 2. 滑动窗口法
i, j, res = 1, 2, []
while j <= target // 2 + 1:
cur_list = list(range(i, j + 1))
cur_sum = sum(cur_list)
if cur_sum < target:
j += 1
elif cur_sum > target:
i += 1
else:
res.append(cur_list)
j += 1
return res
总结
- 数学公式方法性能更优
- 滑动窗口法更通用
附录
本文正在参与「掘金 2021 春招闯关活动」, 点击查看 活动详情