1. 程式人生 > >遞減棧求解下一個更大元素問題

遞減棧求解下一個更大元素問題

首先貼出兩道題:

leetcode739

根據每日 氣溫 列表,請重新生成一個列表,對應位置的輸入是你需要再等待多久溫度才會升高的天數。如果之後都不會升高,請輸入 0 來代替。

例如,給定一個列表 temperatures = [73, 74, 75, 71, 69, 72, 76, 73],你的輸出應該是 [1, 1, 4, 2, 1, 1, 0, 0]

提示:氣溫 列表長度的範圍是 [1, 30000]。每個氣溫的值的都是 [30, 100] 範圍內的整數。

leetcode496

給定兩個沒有重複元素的陣列 nums1 和 nums2 ,其中nums1 是 nums2 的子集。找到 nums1 中每個元素在 nums2

 中的下一個比其大的值。

nums1 中數字 x 的下一個更大元素是指 x 在 nums2 中對應位置的右邊的第一個比 大的元素。如果不存在,對應位置輸出-1。

示例 1:

輸入: nums1 = [4,1,2], nums2 = [1,3,4,2].
輸出: [-1,3,-1]
解釋:
    對於num1中的數字4,你無法在第二個陣列中找到下一個更大的數字,因此輸出 -1。
    對於num1中的數字1,第二個陣列中數字1右邊的下一個較大數字是 3。
    對於num1中的數字2,第二個陣列中沒有下一個更大的數字,因此輸出 -1。

示例 2:

輸入: nums1 = [2,4], nums2
= [1,2,3,4]. 輸出: [3,-1] 解釋:   對於num1中的數字2,第二個陣列中的下一個較大數字是3。 對於num1中的數字4,第二個陣列中沒有下一個更大的數字,因此輸出 -1。

這兩道題都可以歸結為:“在陣列array【i】之後並且大於array【i】的第一個元素在哪”的問題。

我在第二題中使用了雙重for迴圈,很幸運是通過的了。

第一題是明顯不通的。(因為這是中等難度的了)

首先我們檢視一個序列:【1,1,1,1,4】

如果用雙重for迴圈,實際上前4次尋找的都是一個元素而已,就是4.

其實增加了不必要迭代。

遞減棧思路是這樣的:

掃描陣列,如果棧是空的那麼壓如一個元素,因為棧裡沒有元素比這個小,所以肯定要放在最底下。

如果棧不是空的並且當前掃描的元素小於(等於)棧頂元素,壓入。

如果棧不是空的並且掃描元素大於棧頂元素,我們要在不斷彈出元素直至棧頂元素大於當前元素,或者空棧把新元素放入。

我們以第一題的示例來演示遞減棧。

首先有一個空棧:【】。

當前元素73:壓入。【(73,0)】其中0是73的下標,為了到時候放入結果做準備。

當前74,彈出73,放入74.【(74,1)】也就是比73大的第一個元素是74,

當前75,彈出74,放入75.【(75,2)】也就是比74大的一個元素是75.

當前71,壓入。【(75,2),(71,3)】

當前69,壓入。【(75,2),(71,3),(69,4)】

當前72,彈出69,彈出71.也就是比69大的下一個是72,比71大的下一個是72.【(75,2),(72,5)】

當前76,彈出72,75,說明比72,75大的均為76.【(76,6)】

當前73,壓入。【(76,6),(73,7)】

棧不是空的,所以剩餘的兩個元素是沒有下一個更大元素的,可以填入響應特殊值。

這種方法在相當於最好情況的雙重for。沒有多餘的比較。

效率極高,接近O(n)。

附送第一題解:

class Solution:
    def dailyTemperatures(self, temperatures):
        """
        :type temperatures: List[int]
        :rtype: List[int]
        """
        stk=[]
        record=[0 for x in range(len(temperatures))]
        for i,t in enumerate(temperatures):
            if len(stk)==0:
                stk.append((i,t))
            else:
                if t<stk[-1][1]:
                    stk.append((i,t))
                else:
                    while len(stk)>0 and stk[-1][1]<t:
                        index,temp=stk.pop()
                        record[index]=i-index
                    stk.append((i,t))
        return record