1. 程式人生 > 實用技巧 >劍指 Offer 57 - II. 和為s的連續正數序列(雙指標/數學推導法)

劍指 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

  • 解法一:雙指標

仔細想一想這其實是個滑動視窗的題,和為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/