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.
题意:
给定数组nums, 又给定它的子集subNums, 求subNums中每个元素在nums中右边第一个较大元素(即Next Greater Element)
subNums = [4,1,2] 当扫到元素4, 该元素在 nums = [1,3,4,2] 中右边第一个数为2, 并不greater than 4, 返回-1
subNums = [4,1,2] 当扫到元素1, 该元素在 nums = [1,3,4,2] 中右边第一个数为3, 确实greater than 1, 返回 3
subNums = [4,1,2] 当扫到元素2, 该元素在 nums = [1,3,4,2] 中右边没有元素, 不存在greater than 2, 返回-1
思路:
两个指针同时扫 subNums 和 nums
用一个boolean变量做标记,若当前 subNums 元素等于当前nums元素,则标记 found = true ,说明找到了corresponding元素。
nums指针继续往右,找greater element, 直到找到符合 found && nums[j] > subNums[i] 条件的元素。否则返回-1
代码一:
1 class Solution { 2 public int[] nextGreaterElement(int[] subNums, int[] nums) { 3 int[] res = new int[subNums.length]; 4 for (int i = 0; i < subNums.length; i++) { 5 boolean found = false; 6 int j = 0; 7 for (; j < nums.length; j++) { 8 if (found && nums[j] > subNums[i]) { 9 res[i] = nums[j]; 10 break; 11 } 12 if (found && nums[j] < subNums[i]) { 13 res[i] = -1; 14 } 15 if (nums[j] == subNums[i]) { 16 found = true; 17 } 18 } 19 if (j == nums.length) { 20 res[i] = -1; 21 } 22 } 23 return res; 24 } 25 }
另外一个思路就是用单调栈 + HashMap
为何用单调栈? 为任意一个元素找左边和右边第一个比自己大/小的位置,用单调栈。
先只take care of nums : 从右往左扫nums, 用Stack维护递减栈,留下波峰,剔除波谷。比较栈顶元素跟即将入栈元素大小,
用HashMap来记录其比较结果。再take care of nums: 扫一遍subNums,在HashMap中找到对应的value,返回即可。
subNums = [4,1,2], nums = [1,0,3,4,2]
Stack HashMap
^ [2] 2 | -1
^ [4] 4 | -1
^ [4, 3] 3 | 4
^ [4, 3, 0] 0 | 3
^ [4, 3, 1] 1 | 3
代码二:
1 public int[] nextGreaterElement(int[] subNums, int[] nums) { 2 int[] res = new int[subNums.length]; 3 Stack<Integer> stack = new Stack<>(); 4 HashMap<Integer, Integer> map = new HashMap<>(); 5 for (int i = nums.length - 1; i >= 0; i--) { 6 while (!stack.empty() && nums[i] > stack.peek()) { 7 stack.pop(); 8 } 9 if (stack.empty()) { 10 map.put(nums[i], -1); 11 } else { 12 map.put(nums[i], stack.peek()); 13 } 14 stack.push(nums[i]); 15 } 16 17 for (int i = 0; i < subNums.length; i++) { 18 res[i] = map.get(subNums[i]); 19 } 20 return res; 21 }