题目
You are given two arrays (without duplicates) nums1
andnums2
wherenums1
’s elements are subset ofnums2
. Find all the next greater numbers fornums1
's elements in the corresponding places ofnums2
.
The Next Greater Number of a number x in nums1
is the first greater number to its right innums2
. 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.
Note:
- All elements in
nums1
andnums2
are unique. - The length of both
nums1
andnums2
would not exceed 1000.
题意:
给定两个数组(没有重复)nums1 和 nums2 ,nums1 是nums2 的子集。找到nums1中每个元素的在nums2中的下一个比其大的值。
nums1中的x的下一个大的值是该数字x在nums2中,右边的比其大的一个值。如果不存在,返回-1。
THINKING :
1. 肯定不能引入排序,因为排序会将次序打乱,进而破坏问题的条件前提。
2.局部就近匹配,符合栈的特点。(similar to 括号匹配问题)
题目解答
方法1(简洁,技巧):
- 【 栈 】利用栈来为nums2中的每个数字分配下一个最大值。(栈确实能达到此类效果)
- 【 栈的特性 】正常循环的情况下,数组的滚动(游标移动)是向后的,引入栈的时候,则可以有了向前滚动的机会(有了一定的反悔的机会),然后这样子就能够解决一些局部的问题(比如说,寻找相邻的大的数字)。由于栈还可以对于没有价值(已经发现了大的数字)的东西删除,这样子的遗忘功能,简化了搜索空间,问题空间。
Key observation:
Suppose we have a decreasing sequence followed by a greater number
For example [5, 4, 3, 2, 1, 6] then the greater number 6 is the next greater element for all previous numbers in the sequence
We use a stack to keep a decreasing sub-sequence, whenever we see a number x greater than stack.peek() we pop all elements less than x and for all the popped ones, their next greater element is x
For example [9, 8, 7, 3, 2, 1, 6]
The stack will first contain [9, 8, 7, 3, 2, 1] and then we see 6 which is greater than 1 so we pop 1 2 3 whose next greater element should be 6
public int[] nextGreaterElement(int[] findNums, int[] nums) {
Map<Integer, Integer> map = new HashMap<>(); // map from x to next greater element of x
Stack<Integer> stack = new Stack<>();
for (int num : nums) {
while (!stack.isEmpty() && stack.peek() < num)
map.put(stack.pop(), num);
stack.push(num);
}
for (int i = 0; i < findNums.length; i++)
findNums[i] = map.getOrDefault(findNums[i], -1);
return findNums;
}
方法2(复杂,一般):
public int[] nextGreaterElement(int[] findNums, int[] nums) {
int results[] = new int[findNums.length]; for (int j = 0; j < findNums.length; j++) { boolean findBigger = false; boolean isRight = false; for (int i = 0; i < nums.length; i++) { if (nums[i] == findNums[j]) { isRight = true; } if (isRight && findNums[j] < nums[i]) { results[j] = nums[i]; findBigger = true; break; } } if (!findBigger) { results[j] = -1; } } return results; }