題目描述:
根據每日氣溫列表,請重新生成一個列表,對應位置的輸入是你需要再等待多久溫度纔會升高超過該日的天數。如果之後都不會升高,請在該位置用 0 來代替。
例如,給定一個列表 temperatures = [73, 74, 75, 71, 69, 72, 76, 73],你的輸出應該是 [1, 1, 4, 2, 1, 1, 0, 0]。
提示:
氣溫 列表長度的範圍是 [1, 30000]。每個氣溫的值的均爲華氏度,都是在 [30, 100] 範圍內的整數。
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/daily-temperatures
著作權歸領釦網絡所有。商業轉載請聯繫官方授權,非商業轉載請註明出處。
解題思路:
對於給定的temperatures數組T,對於任意位置的值,只需要找到下一個比當前值大的值即可。所以,最直接的方法應該是從頭開始遍歷數組,暴力法解決問題。但是這種辦法在數據量變大的時候,測試會出現超時問題。
所以考慮是否可以對數組進行剪枝操作。
用數組result記錄結果,如果反向遍歷數組T,那麼
當T[m]<T[i]時,直接給result[i]賦值爲len(T)-i。
當T[m]>T[i]時,把元素i去掉,因爲該元素之前有比它大的元素,所以它不會再起作用,進行下一個循環。
核心思想就是在反向遍歷過程中,如果出現比當前元素大的值,則當前元素將不再對結果起任何作用,因爲被它之前的值擋住了。
代碼如下:
class Solution:
def dailyTemperatures(self, T):
temp = [0 for i in range(len(T))]
while T:
t = T.pop()
for i in range(len(T)-1,-1,-1):
if T[i] >= t:
break
else:
temp[i] = len(T)-i
return temp
測試結果:
改進思路:
依然反向遍歷,但是在遍歷過程中,使用棧來記錄不同日期t值的位置信息。並使棧承單調排列,還是核心思想,如果前一位的值比後一位的值大,則後一位的值將不再起作用,即可以從出棧。
代碼如下:
class Solution:
def dailyTemperatures(self, T):
temp = [0 for i in range(len(T))]
size = len(T)
stack = [size-1]
for i in range(size-2,-1,-1):
while stack and T[i] >= T[stack[-1]]:
stack.pop()
stack.append(i)
if len(stack) > 1:
temp[i] = stack[-2] - stack[-1]
return temp
測試結果:
總結:
通過創建輔助棧,進行對溫度進行排序,可以大大縮減時間。主要還是要搞清楚什麼時候應該用棧這種數據結構,像這道題中,輔助棧中的末尾元素可以被後進來的元素“擠掉”,這就是典型的LIFO。這道題還有一種正向遍歷的思路的類似思路。代碼如下:
class Solution:
def dailyTemperatures(self, T):
size = len(T)
temp = [0 for i in range(size)]
stack = []
for i in range(size):
while stack and T[i] > T[stack[-1]]:
last_i = stack.pop()
temp[last_i] = i - last_i
stack.append(i)
return temp