• 剑指 Offer 57


    • 题目描述

    输入一个正整数 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

    • 解法一:双指针

    仔细想一想这其实是个滑动窗口的题,和为target的list是连续的,因此我们可以想到可以用一个指针p1从左往右遍历一遍数组,然后用一个p2,从p1往后遍历。什么时候p2停止呢,就是当p1, p2围成的数组的和刚好等于target的时候,此时则说明p2再往后遍历,那么p1,p2指针围成的数组的和则会大于target了。此时,左指针p1应该往右移,此时才能继续找和到target的序列,此时p2则又往右继续遍历,直到找到下一个和等于target的序列或者大于target的序列,此时p1又往右移动。

    指针结束移动的条件是当p1越过target的中值,为什么是中值的呢?可以想象其实大于中值后,两个及两个元素以上的序列和肯定大于target了。

    直接上代码:

        def findContinuousSequence(self, target):
            p1, p2 = 1, 2
            alist = []
            currentSum = p1 + p2
            while p1 <= (target +1) //2:
                if currentSum == target:
                    alist.append([i for i in range(p1, p2+1)])
                    currentSum -= p1
                    p1 += 1
                elif currentSum < target:
                    p2 += 1
                    currentSum += p2
                elif currentSum > target:
                    currentSum -= p1
                    p1 += 1
            return alist
    • 解法二:求根法

    代码:

    class Solution:
        def findContinuousSequence(self, target: int):
            # 创建输出列表
            res = []
    
            # y不能超过target的中值,即y<=target//2 + 1,range函数左开右闭,所以这里是+2
            for y in range(1,target//2 + 2):
                # 应用我们的求根公式
                x = (1/4 + y**2 + y - 2 * target) ** (1/2) + 0.5
                # 我们要确保x不能是复数,且x必须是整数
                if type(x) != complex and x - int(x) == 0:
                    res.append(list(range(int(x),y+1)))
            
            return res

    我觉得求根法和间隔法在面试的时候不一定想得到,就算想到了在面试的时候也不一定推得对。

    • 解法三:间隔法

     

     代码:

        #数学求解+间隔计算:
        def findContinuousSequence(self, target: int) -> List[List[int]]:
            i, res = 1, []
            while i * (i + 1) / 2 < target:
                if (target - i * (i+1)/2) % (i + 1) == 0:
                    x = int((target - i * (i+1)/2) // (i + 1))
                    res.append(list(range(x, x+i+1)))
                i += 1
            return res[::-1]

     参考题解:https://leetcode-cn.com/problems/he-wei-sde-lian-xu-zheng-shu-xu-lie-lcof/solution/xiang-jie-hua-dong-chuang-kou-fa-qiu-gen-fa-jian-g/

  • 相关阅读:
    类函数指针
    resource for machine learning
    蒲丰投针与蒙特卡洛模拟
    IIS5、IIS6、IIS7的ASP.net 请求处理过程比较
    CMD 命令速查手册
    Process, Thread, STA, MTA, COM object
    在托管代码中设置断点(Windbg)
    SidebySide Execution
    .NET Framework 3.5 Architecture
    Overview of the .NET Framework
  • 原文地址:https://www.cnblogs.com/yeshengCqupt/p/13455185.html
Copyright © 2020-2023  润新知