1. 程式人生 > 實用技巧 >面試不知如何回答這六大知識點,你還敢說熟悉MySQL?

面試不知如何回答這六大知識點,你還敢說熟悉MySQL?

496. 下一個更大元素 I

  給定兩個 沒有重複元素 的陣列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。

方法一:單調棧
我們可以忽略陣列 nums1,先對將 nums2 中的每一個元素,求出其下一個更大的元素。隨後對於將這些答案放入雜湊對映(HashMap)中,再遍歷陣列 nums1,並直接找出答案。對於 nums2,我們可以使用單調棧來解決這個問題。

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

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

public class Solution {
    public int[] nextGreaterElement(int[] findNums, int[] nums) {
        Stack < Integer > stack = new Stack < > ();
        HashMap < Integer, Integer > map = new HashMap < > ();
        int[] res = new int[findNums.length];
        for (int i = 0; i < nums.length; i++) {
            while (!stack.empty() && nums[i] > stack.peek())
                map.put(stack.pop(), nums[i]);
            stack.push(nums[i]);
        }
        while (!stack.empty())
            map.put(stack.pop(), -1);
        for (int i = 0; i < findNums.length; i++) {
            res[i] = map.get(findNums[i]);
        }
        return res;
    }
}