[英]How to optimise a strictly increasing stack based list
所以我正在嘗試解決https://leetcode.com/problems/daily-temperatures基本上給定一個數組 [30,40,50,60] 我們需要返回下一個遞增值的索引,因此 output 將是 [1, 1,1,0] 我的算法是
我一直在這里超出時間限制,我的理解是復雜度是 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)
例如,如果k
為2
,我們會這樣做。
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.