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.
Note:
- All elements in
nums1
andnums2
are unique. - The length of both
nums1
andnums2
would not exceed 1000.
题目大意:给定两个整型数组,nums1是nums2的子数组,nums1和nums2中都没有重复的元素。对nums1中的每个数,寻找它在nums2中对应数字的右边的第一个比它大的数,如果不存在则为-1,将结果存放在一个数组中返回。
解题思路:
解法一:暴力解法,遍历nums1,对其中的每个数,在nums2中找到该数,然后在nums2中该数的右边找第一个较大的数。
代码如下:(13ms,beats 37.66%)
public int[] nextGreaterElement(int[] findNums, int[] nums) {
int findLen = findNums.length;
int numsLen = nums.length;
int i, j, k;
int[] res = new int[findLen];
for (i = 0; i < findLen; i++) {
for (j = 0; j < numsLen; j++) {
if (findNums[i] == nums[j]) {
for (k = j + 1; k < numsLen; k++) {
if (nums[k] > findNums[i]) {
res[i] = nums[k];
break;
}
}
if (k == numsLen)
res[i] = -1;
break;
}
}
}
return res;
}
解法二:首先确定nums2中每一个数和右边第一个较大数的关系。方法为维护一个栈和一个map,从尾到头遍历nums2,对于每一个数,如果栈顶元素小于该数,则栈顶元素出栈,直到找到大于该数的栈顶元素,此时将<该数,栈顶元素>放入map中,然后将该数也入栈;如果栈空了,则将<该数,-1>放入map中,同样将该数入栈。确定好这样一个关系后,就可以直接遍历nums1,对每一个元素直接在map中执行get,就可以确定nums2中下一个较大元素的值了。
代码如下:(14ms,beats 31.75%,没想到比暴力解法还慢- -)
public int[] nextGreaterElement(int[] findNums, int[] nums) {
int findLen = findNums.length;
int numsLen = nums.length;
int[] res = new int[findLen];
if (findLen == 0 || numsLen == 0 || findLen > numsLen)
return res;
Map<Integer, Integer> map = new HashMap<>();
int[] stack = new int[numsLen];
int index = -1;
int i, j;
int curMax = nums[numsLen - 1];
map.put(curMax, -1);
for (i = numsLen - 1; i >= 0; i--) {
while (index >= 0) {
if (nums[i] > stack[index])
--index;
else {
map.put(nums[i], stack[index]);
stack[++index] = nums[i];
break;
}
}
if (index < 0) {
map.put(nums[i], -1);
stack[++index] = nums[i];
}
}
for (j = 0; j < findLen; j++) {
res[j] = map.get(findNums[j]);
}
return res;
}