1. 程式人生 > >LeetCode:每日溫度【739】

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;

    }