leetcode 496/503 下一個更大的元素1,2(單調棧解法)

【leetcode 496 題目】

給定兩個沒有重複元素的數組 nums1 和 nums2 ,其中nums1 是 nums2 的子集。找到 nums1 中每個元素在 nums2 中的下一個比其大的值。

nums1 中數字 x 的下一個更大元素是指 x 在 nums2 中對應位置的右邊的第一個比 x 大的元素。如果不存在,對應位置輸出-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。
注意:

nums1和nums2中所有元素是唯一的。
nums1和nums2 的數組大小都不超過1000。

【leetcode 503 題目】

給定一個循環數組(最後一個元素的下一個元素是數組的第一個元素),輸出每個元素的下一個更大元素。
數字 x 的下一個更大的元素是按數組遍歷順序,這個數字之後的第一個比它更大的數,
這意味着你應該循環地搜索它的下一個更大的數。如果不存在,則輸出 -1。

示例 1:

輸入: [1,2,1]
輸出: [2,-1,2]
解釋: 第一個 1 的下一個更大的數是 2;
數字 2 找不到下一個更大的數;
第二個 1 的下一個最大的數需要循環搜索,結果也是 2。
注意: 輸入數組的長度不會超過 10000。

【分析】

從題目中我們可以看出,496題和503題都是尋找每一個元素的下一個更大的元素,不同的是:在496題中,只需要遍歷數組一遍,而且數組中的元素是不可重複的,而503題中數組是循環數組,意味着可以循環遍歷,而且題目中沒有指出數組元素不可重複。

我在分析這兩個題目的時候都使用了單調棧的方法,下面是具體的分析過程。

【496題】

總體思想:忽略數組 nums1,先對將 nums2 中的每一個元素,求出其下一個更大的元素。隨後對於將這些答案放入哈希映射(HashMap)中,再遍歷數組 nums1,並直接找出答案。對於 nums2,我們可以使用單調棧來解決這個問題。

  1. 把第一個元素 nums2[1] 放入棧,
  2. 對於第二個元素 nums2[2],如果 nums2[2] > nums2[1],那麼我們就找到了 nums2[1] 的下一個更大元素 nums2[2],此時就可以把 nums2[1] 出棧並把 nums2[2] 入棧;如果 nums2[2] <= nums2[1],我們就僅把 nums2[2] 入棧。
  3. 對於第三個元素 nums2[3],此時棧中有若干個元素,那麼所有比 nums2[3] 小的元素都找到了下一個更大元素(即 nums2[3]),因此可以出棧,在這之後,我們將 nums2[3] 入棧,以此類推。

可以發現,我們維護了一個單調棧,棧中的元素從棧頂到棧底是單調不降的。當我們遇到一個新的元素 nums2[i] 時,我們判斷棧頂元素是否小於 nums2[i],如果是,那麼棧頂元素的下一個更大元素即爲 nums2[i],我們將棧頂元素出棧。重複這一操作,直到棧爲空或者棧頂元素大於 nums2[i]。此時我們將 nums2[i] 入棧,保持棧的單調性,並對接下來的 nums2[i + 1], nums2[i + 2] ... 執行同樣的操作。那麼,由於數組中的元素不重複,則不同元素對應的下一個更大元素都可以在hash表中尋找到。

【503題】

總體思想:和496題相似,維護一個單調棧(單調遞增棧),同時創建一個hash表,但是在hash表中存放的是索引值,這樣就可以避免重複元素導致的結果錯誤。

重要一點:需要將兩個相同的數組拼接成一個數組,相當於循環數組了。

【Python代碼:496】

class Solution:
    #暴力解法 256m
    def nextGreaterElement1(self, nums1: list, nums2: list) -> list:
        nums1_length = len(nums1)
        nums2_length = len(nums2)
        result = []
        for i in range(nums1_length):
            for j in range(nums2_length):
                if nums2[j] == nums1[i]:
                    k = j + 1
                    flag = 0
                    while k < nums2_length:
                        if nums2[k] > nums1[i]:
                            flag = 1
                            result.append(nums2[k])
                            break
                        else:
                            k += 1
                    if flag == 0:
                        result.append(-1)
                    break
        return result
    #單調棧解法 56m
    def nextGreaterElement(self, nums1: list, nums2: list) -> list:
        hash_nums2 = {}
        stack_nums2 = []
        result = []
        stack_nums2.append(nums2[0])
        if len(nums1) == 0 or len(nums2) == 0:
            return result
        for i in range(1,len(nums2)): #維護一個單調遞增棧,當前元素大於棧頂元素時將鍵值對存入hash表中,將棧頂元素出棧,並將當前元素入棧,如果當前元素小於棧頂元素則將當前元素入棧
            if nums2[i] <= stack_nums2[-1]:
                stack_nums2.append(nums2[i])
            else:
                while len(stack_nums2) != 0 and nums2[i] > stack_nums2[-1]:
                    hash_nums2[stack_nums2[-1]]=nums2[i]
                    stack_nums2.pop()
                stack_nums2.append(nums2[i])
        if len(stack_nums2) != 0:
            for i in stack_nums2:
                hash_nums2[i] = -1
        for i in nums1:
            result.append(hash_nums2[i])
        return result

s = Solution()
nums1 = [4,1,2]

nums2 = [1,3,4,2]
print(s.nextGreaterElement(nums1,nums2))

 

【Python代碼 503】

class Solution:
    def nextGreaterElements(self, nums: list) -> list:
        nums_new = []
        i = 0
        while i < 2:
            for j in nums:
                nums_new.append(j)
            i += 1
        hash_nums = {}
        stack_nums = []
        index_nums = []
        result = []
        stack_nums.append(nums[0])
        index_nums.append(0)
        for i in range(1,len(nums_new)):
            if nums_new[i] <= stack_nums[-1]:
                stack_nums.append(nums_new[i])
                index_nums.append(i)
            else:
                while len(stack_nums) != 0 and nums_new[i] > stack_nums[-1]:
                    hash_nums[index_nums[-1]] = nums_new[i]
                    stack_nums.pop()
                    index_nums.pop()
                stack_nums.append(nums_new[i])
                index_nums.append(i)
        if len(index_nums) != 0:
            for i in index_nums:
                hash_nums[i] = -1
        for i in range(len(nums)):
             result.append(hash_nums[i])
        return result


s = Solution()
nums = [100,1,11,1,120,111,123,1,-1,-100]
print(s.nextGreaterElements(nums))

 

發佈了27 篇原創文章 · 獲贊 2 · 訪問量 1767
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章