LeetCode:每日溫度【739】
LeetCode:每日溫度【739】
題目描述
根據每日 氣溫
列表,請重新生成一個列表,對應位置的輸入是你需要再等待多久溫度才會升高的天數。如果之後都不會升高,請輸入 0
來代替。
例如,給定一個列表 temperatures = [73, 74, 75, 71, 69, 72, 76, 73]
,你的輸出應該是 [1, 1, 4, 2, 1, 1, 0, 0]
。
提示:氣溫
列表長度的範圍是 [1, 30000]
。每個氣溫的值的都是 [30, 100]
範圍內的整數。
題目分析
說實話,看到這個題的時候,我下意識的想法是,兩個For迴圈就可以解決,因為是找到第一個大於當前溫度的溫度,所以並不認為時間複雜度為N的平方。並且程式碼也順利通過了。可這畢竟是一道中等難度的題目,我們還是要進一步思考一下如何優化。
首先呢,我們不要從頭到尾遍歷,而是反過來,因為如果是從前向後遍歷的話,先遍歷第一天,我們需要記錄下載第一天的溫度,然後遍歷到第二天,需要用第二天的溫度和第一天左比較,發現第二天比第一天溫度高,所以又要返回去修改第一天的結果,將其設定為1。
如果是從後向前遍歷的話,先遍歷第二天,我們需要記錄下第二天的溫度,然後遍歷到第一天,需要用第一天和第二天的溫度作比較,發現第一天的氣溫比第二天的低,此時我們可以直接修改第一天(也就是當前遍歷的位置)的結果,將其設定為1。
所以從分析來看,從後向前遍歷比較好一點,因為兩者都是需要記錄下一系列資訊,但是從前向後遍歷的話還需要返回去進行修改結果,但是從後向前遍歷的話只需要修改當前的結果即可
我們在棧中儲存當前的氣溫的下標,[為什麼不儲存值呢?知道下標,我們用temperatures[i]就可以知道值啊,並且我們還多儲存了一個位置資訊]。棧頂溫度一定是離當前溫度最近的溫度位置。
如果當前溫度,大於棧頂溫度的話,說明棧頂溫度的位置不是下一個回升的溫度,那我們就要更換棧頂,即出棧操作,一直比較,知道找到小於棧頂溫度。接著當前溫度小於棧頂溫度,那輸出應該是stack.peek()-i;
Java題解
public int[] dailyTemperatures(int[] temperatures) { int[] res = new int[temperatures.length]; Stack<Integer> stack = new Stack<>(); for (int i =temperatures.length-1;i>=0; i--){ while (!stack.isEmpty()&&temperatures[i]>=temperatures[stack.peek()]) stack.pop(); if(stack.isEmpty()) res[i] = 0; else res[i] = stack.peek()-i; stack.push(i); } return res; }