1. 程式人生 > >LeetCode#496: Next Greater Element I

LeetCode#496: Next Greater Element I

Description

You are given two arrays (without duplicates) nums1 and nums2 where nums1’s elements are subset of nums2. Find all the next greater numbers for nums1’s elements in the corresponding places of nums2.

The Next Greater Number of a number x in nums1 is the first greater number to its right in nums2. If it does not exist, output -1 for this number.

Example

Input: nums1 = [4,1,2], nums2 = [1,3,4,2].
Output: [-1,3,-1]
Explanation:
    For number 4 in the first array, you cannot find the next greater number for it in the second array, so output -1.
    For number 1 in the first array, the next greater number for it in the second array is 3.
    For number 2 in the first array, there is no next greater number for it in the second array, so output -1.
Input: nums1 = [2,4], nums2 = [1,2,3,4].
Output: [3,-1]
Explanation:
    For number 2 in the first array, the next greater number for it in the second array is 3.
    For number 4 in the first array, there is no next greater number for it in the second array, so output -1.

Solution

這道題的題目理解起來比較費勁,它的意思就是在nums1中的每個數字找到nums2中這個數字右邊第一個比它大的數字。例如在上面給的Example中,nums1中的數字2在nums2中右邊第一個比它大的數字是3,那麼就返回3;而對於nums1中的4,nums2中的4右邊已經到了邊界,所以沒有比它大的數字,因此返回-1。

理清了題目的意思後,我們就開始想想該如何解這道題。以nums1 = [4,1,2], nums2 = [1,3,4,2,5]為例,我們忽略nums1的內容而檢視nums2中每個數字的解可以得到1的解為3,3的解為4,4的解為5,2的解為5,而其中4、1、2是在nums1中出現的,因此返回[5,3,5],這裡我們不妨使用一個map來儲存nums2中每個元素的解,再遍歷nums1看看元素在map中是否存在。

以上思路中最核心的一個問題在於該如何得到nums2中每個元素的解。我們可以使用棧來實現,首先將nums2中的第一個元素1加入棧中,而第二個元素3大於棧頂的元素,因此將棧中的1彈出並且將(key = 1, value = 3)放入map中,再將3壓入棧;第三個元素4大於棧頂的元素,因此執行上面同樣的操作,將3彈出並將(key = 3, value = 4)放入map中,再將4壓入棧;第四個元素2小於棧頂元素,因此直接壓入棧,此時棧中元素有[4, 2];第五個元素5大於棧頂元素,因此將2彈出,並將(key = 2, value = 5)放入map中,而此時5依然大於棧頂元素4,也將4彈出並將(key = 4, value = 5)放入map中。如此反覆,我們就將nums2中有解的鍵值對都放入了map中,再遍歷nums1中取出每個元素的解即可。

class Solution {
    public int[] nextGreaterElement(int[] nums1, int[] nums2) {
        Map<Integer, Integer> map = new HashMap<>();
        Stack<Integer> stack = new Stack<>();
        for(int num : nums2) {
        	while(!stack.isEmpty() && stack.peek() < num) {
        		map.put(stack.pop(), num);
        	}
        	stack.push(num);
        }
        for(int i = 0; i < nums1.length; i++) {
        	nums1[i] = map.getOrDefault(nums1[i], -1);
        }
        return nums1;
    }
}