簡體   English   中英

如何優化嚴格遞增的基於堆棧的列表

[英]How to optimise a strictly increasing stack based list

所以我正在嘗試解決https://leetcode.com/problems/daily-temperatures基本上給定一個數組 [30,40,50,60] 我們需要返回下一個遞增值的索引,因此 output 將是 [1, 1,1,0] 我的算法是

  1. while end !=0 從數組中讀取
  2. 如果最后一個元素將 0 添加到 output 並堆棧
  3. 否則,如果 temperature[end] > stack top add to stack 和 add stack top 作為溫度差。
  4. 如果 temperature[end] <= stack top,那么我們會彈出每個元素,直到此條件中斷並更新 stack top 和 output。

我一直在這里超出時間限制,我的理解是復雜度是 O(N)。 我不確定如何進一步優化它。

def dailyTemperatures(self, temperatures: List[int]) -> List[int]:
        output = []
        r = len(temperatures) - 1
        stack = []
        while r >= 0:
            if r == len(temperatures) - 1:
                stack.append(r)
                output.insert(0, 0)
            else:
                if temperatures[stack[-1]] > temperatures[r]:
                    output.insert(0, stack[-1]-r)
                    stack.append(r)
                else:
                    while stack and temperatures[stack[-1]] <= temperatures[r]:
                        stack.pop()
                    if len(stack) == 0:
                        output.insert(0, 0)
                        stack.append(r)
                    else:
                        output.insert(0, stack[-1]-r)
                        stack.append((r))

            r -= 1
        return output

慢速算法的有效實現仍將緩慢擴展。 優化堆棧不會改變大 O。 但我將使用不同的數據結構概述一個想法,供您理解。

在問題的 example1 中,您從數組[73,74,75,71,69,72,76,73]開始。 讓我們根據范圍的最大值來安排它,如下所示:

x = [
    [73,74,75,71,69,72,76,73],
    [   74,   75,   72,   76],
    [         75,         76],
    [                     76],
]

換句話說x[i][j]給出從j * 2**i(j+1) * 2**i - 1的所有元素的最大值。

現在要找到k之后的第一個上升,我們 go “向前和向下”直到我們找到一個更大的塊(如果沒有,則為 0)然后“向上和向前”直到我們找到它的位置。 在哪里:

在 (i, j) 處向前和向下時:如果 j 是偶數:如果 j 不在 x[i] 的末尾:移動到 (i, j+1) 然后測試 else:答案為 0 else: 移動到 (i +1, j//2 + 1) 然后測試

在 (i, j) 向上和前進時 0 < i:如果答案在 (i-1, j+j) 的范圍內:移動到 (i-1, j+j) 否則:移動到 (i-1 , j+j+1)

例如,如果k2 ,我們會這樣做。

start at (0, 2)
go f&d to (0, 3), check if 75 < x[0][3] (ie 71), stay f&d
go f&d to (1, 2), check if 75 < x[1][2] (ie 72), stay f&d
go f&d to (1, 3), check if 75 < x[1][3] (ie 76), switch to u&f
check if 75 < x[0][6] (ie 76) go u&f to (0, 6)

現在我們知道下一個在 position 6。所以我們得到6 - 2 == 4那里。

表現如何? 整個數據結構是O(n)來構建的。 每個查找最壞的情況是O(log(n)) 所以做n次檢查是最壞的O(n log(n)) 這應該足夠快。

我的解決方案是

def dailyTemperatures(self, temperatures):
    res = []
    i = 0
    while i < len(temperatures) - 1:
        j = i + 1
        while True:
            if j >= len(temperatures):
                res.append(0)
                break
            if temperatures[j] <= temperatures[i]:
                j += 1
            else:
                res.append(j - i)
                break
        i += 1
    res.append(0)
    return res
    

經過大量測試,您的答案是線性的。 (因此比我之前建議的要好。)但是,為了滿足他們的時間限制,您需要對所有內容進行微優化。 意思是去掉所有不需要的if ,確保你的比較是最快的,等等。

我肯定會說 leetcode 對問題和語言性能設置的時間限制過於嚴格。

def dailyTemperatures(self, temperatures: List[int]) -> List[int]:
    if 0 == len(temperatures):
        return []
    output = [0]
    r = len(temperatures) - 1
    stack = [r]
    r -= 1
    while r >= 0:
        while len(stack) and temperatures[stack[-1]] <= temperatures[r]:
            stack.pop()
        if len(stack) == 0:
            output.append(0)
        else:
            output.append(stack[-1]-r)
        stack.append((r))
        r -= 1
    output.reverse()
    return output

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM