力扣LeetCode 739題 每日溫度(單調棧)

2021-10-07 03:41:15 字數 1692 閱讀 1917

題目:

分析:題目的意思應該叫做「對於陣列的每乙個元素,尋找下乙個比他大的元素與他的距離」。例如對於 73 下標為 0 ,下乙個比他大的元素為 74 下標為 1 ,那麼就填入 1-0=1 。以此類推。

直接能夠想到的方法就是暴力遍歷,對於每乙個元素向後遍歷:

class

solution

//跳出之後沒超範圍,說明是合法找到

if(jelse

}return ans;

}}

時間空間都比較差,最差的情況下,試想,如果溫度全部是降序,那麼對於每乙個元素,都會遍歷一整遍到陣列末尾,那麼時間複雜度是 o(n2)。

由於之前做過最大矩形面積的題目,用過單調棧這個東西,因此想到了他。

回想一下在示例中:[73, 74,75, 71, 69, 72, 76,73]

上一種方法在 75~76 這段,做了很多重複的工作。

實際上當 75 找到比他大的答案是 76 的時候,這兩者中間幾個元素的答案範圍相應縮小了,但是暴力的做法卻仍然在盲目進行。所以我們想到用單調棧。

維護乙個單調遞減的棧,但是不是維護陣列的值,而是下標,每次判斷用下標到陣列裡去取值。

知道定義之後,我們選擇先來模擬這種方法的步驟,更加方便的計算結果:

可以看到如果使用單調棧,上面會有兩個連續出棧的過程,這就是相比暴力法改進了很多的地方。

確定了處理流程之後,我們還要考慮實現的一些細節:

遞減的條件是 >= 還是 > ? 是 >=;(試想 [ 1 ,1 ,2 ]對於第乙個 1 的答案應該是 2-0=2,所以第二個 1 也要入棧)

出棧的條件是 < ,什麼情況入棧呢?看到上面的例子裡在啊 i =5 的時候是有連續出棧的,因此只要滿足 < 需要連續出棧,while 迴圈來封裝。

class

solution

stack.

push

(i);

//如果沒有異常就入棧

i++;}

return ans;

}}

直接使用暴力法能否再進一步改進呢?

如果倒過來看這個問題,ans 仍然記為結果陣列。

以題目的示例來看這個過程:[73, 74, 75, 71, 69, 72, 76, 73]

到這一步的時候我們發現了兩個問題:

這樣利用後面結果的「跳躍查詢」方式,比暴力法合理了很多;

如果一次跳躍之後仍然得不到結果,比如 ans[4] !=0,

但是,對應的 t[ 4+ans[4] ] 也並不 > 當前的 t[i] ,那麼如果對應的

ans[ 5 ]!=0,就不能停止,而要繼續跳躍。

這種做法應該是動態規劃,狀態轉移方程就是:

從第二種情況看,「前乙個狀態」並不能完全解決當前狀態的問題,有可能會繼續追溯,個人認為這種方法更像是跳躍的遞迴而不是動態規劃。

但是這道題目,可能對棧的使用和頻繁增刪操作,時間大於陣列的直接訪問,用這種遞迴方法時間遠遠比單調棧少?(又或者只是力扣日常出bug)

最終**如下:

class

solution

else

if(res[j]==0

)}}return res;

}}

LeetCode 739題 每日溫度

請根據每日 氣溫 列表,重新生成乙個列表。對應位置的輸出為 要想觀測到更高的氣溫,至少需要等待的天數。如果氣溫在這之後都不會公升高,請在該位置用 0 來代替。例如,給定乙個列表 temperatures 73,74,75,71,69,72,76,73 你的輸出應該是 1,1,4,2,1,1,0,0 ...

LeetCode 739 每日溫度

根據每日 氣溫 列表,請重新生成乙個列表,對應位置的輸入是你需要再等待多久溫度才會公升高的天數。如果之後都不會公升高,請輸入 0 來代替。例如,給定乙個列表 temperatures 73,74,75,71,69,72,76,73 你的輸出應該是 1,1,4,2,1,1,0,0 static con...

LeetCode 739 每日溫度

根據每日 氣溫 列表,請重新生成乙個列表,對應位置的輸入是你需要再等待多久溫度才會公升高的天數。如果之後都不會公升高,請輸入 0 來代替。例如,給定乙個列表 temperatures 73,74,75,71,69,72,76,73 你的輸出應該是 1,1,4,2,1,1,0,0 從後一天往前一天推,...