LeetCode | 496. Next Greater Element I

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 1:
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.
Example 2:
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.


關鍵在於理解題意,對於nums1中每一個數,在nums2中相同的數的位置的右邊,找到第一個大於它的數。
第一種方法簡單粗暴。O(n2)的複雜度,beats 16%。

public class Solution {
    public int[] nextGreaterElement(int[] findNums, int[] nums) {
        int[] output = new int[findNums.length];
        //循環判斷nums1的每個數
        for(int i = 0; i < findNums.length; i++) {
            //先預置找不到最大值,即-1
            output[i] = -1;
            //遞減找到最近的great number,如果遞減到兩個數相等,說明相同數以右沒有大於他的數
            for(int j = nums.length - 1; j >= 0; j--) {
                if(nums[j] == findNums[i]) break;
                if(nums[j] > findNums[i]) output[i] = nums[j];
            }
        }
        return output;
    }
}

後來Discuss中看到了一種相當巧妙的思路:Discuss鏈接,考慮到找greater number是從最右邊開始的,可以利用stack和map來維護這個過程。從查詢數組最右邊開始循環,當棧頭有比當前數小的值時則彈出,直到找到大於當前數的值,即是當前數的greater number,將這對數存到map中,並將當前數保存到棧內。可以發現,循環後的棧是查詢數組的逆序保存,恰好和題目所要求的從右邊找起的目的契合。通過這個算法時間複雜度一下幹到了O(n),膜拜=。=

public class Solution {
    public int[] nextGreaterElement(int[] findNums, int[] nums) {
        Map<Integer, Integer> map = new HashMap<>();
        Stack<Integer> stack = new Stack<>();
        for(int i = nums.length-1; i>=0; i--){
            while(!stack.empty() && nums[i]>stack.peek()) stack.pop();
            map.put(nums[i], (stack.empty())? -1 : stack.peek());
            stack.push(nums[i]);
        }
        for(int i = 0; i<findNums.length; i++){
            findNums[i] = map.get(findNums[i]);
        }
        return findNums;       
    }
}
發佈了84 篇原創文章 · 獲贊 0 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章