[剑指 Offer 57 - II. 和为s的连续正数序列] | 刷题打卡

136 阅读1分钟

今天我们来做一道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 春招闯关活动」, 点击查看 活动详情