题目描述:
给你两个 没有重复元素 的数组 nums1 和 nums2 ,其中nums1 是 nums2 的子集。
请你找出 nums1 中每个元素在 nums2 中的下一个比其大的值。
nums1 中数字 x 的下一个更大元素是指 x 在 nums2 中对应位置的右边的第一个比 x 大的元素。如果不存在,对应位置输出 -1 。
示例 1:
输入: nums1 = [4,1,2], nums2 = [1,3,4,2].
输出: [-1,3,-1]
解释:
对于 num1 中的数字 4 ,你无法在第二个数组中找到下一个更大的数字,因此输出 -1 。
对于 num1 中的数字 1 ,第二个数组中数字1右边的下一个较大数字是 3 。
对于 num1 中的数字 2 ,第二个数组中没有下一个更大的数字,因此输出 -1 。
#### 示例 2:
输入: nums1 = [2,4], nums2 = [1,2,3,4].
输出: [3,-1]
解释:
对于 num1 中的数字 2 ,第二个数组中的下一个较大数字是 3 。
对于 num1 中的数字 4 ,第二个数组中没有下一个更大的数字,因此输出 -1 。
难度 Easy
解题思路:
解法一: brute force
- 遍历nums1,从num2从找比他大的,把找到后的数push到 存储结果的数组中。找不到的话,push -1
- 时间复杂度,O(N2)
var nextGreaterElement = function(nums1, nums2) {
var obj2 = {}
var res = []
var len1 = nums1.length;
var len2 = nums2.length;
for(var i = 0; i < len2; i++) {
obj2[nums2[i]] = i;
}
for(var j = 0; j < len1; j++) {
// 在num2中的索引
var index = obj2[nums1[j]];
var m = index;
var found = false
while(m < len2) {
if(nums1[j] < nums2[m]) {
res.push(nums2[m])
found = true;
break;
}
m++;
}
if(!found) res.push(-1)
}
return res;
};
解法二: 单调栈
如图,第一个挡住视野的元素,就是前边元素的 下一个最大的元素。
单调栈: 顾名思义,栈里边的元素是单调递增或者递减的
解法:
- 维护一个单调递增栈,一个map记录当前元素跟下一个最大元素的关系
- 元素入栈的时候,跟栈顶元素比较
- 如果待入栈元素大于栈顶元素,则栈顶元素出栈,记录关系,map[top]= 待入栈元素
- 如果待入栈元素小于栈顶元素,则表明,此元素不是栈顶的 下一个最大的元素。直接把此元素入栈
- 最后栈内有剩余元素,说明没有找到,返回-1
举例: 操作步骤:
- 元素 1 入栈,3等待入栈。
| 元素 | 待入栈 |
|---|---|
| 1 | 3 |
-
比较待入栈元素 3 大于 1。1 出栈,3入栈,记录 map[1] = 3; | 元素 |待入栈| | --- | --- | | 3| 4|
-
比较待入栈元素 4 大于 3。3 出栈,4入栈,记录 map[3] = 4; | 元素 |待入栈| | --- | --- | | 4| 2|
-
比较待入栈元素 2 小于 4。2直接入栈,栈内剩下 4,2都没有下一个最大的元素,赋值 -1 | 元素 | | --- | | 2| | 4|
-
最终 map的值为
{1:3,3:4} -
遍历num1 从map中找对应的key,找不到就赋值成-1
代码:
var nextGreaterElement = function(nums1, nums2) {
const nextMap = {};
const stack = [];
const res = []
for(let i = 0; i < nums2.length;i++) {
// 拿到栈顶元素
let top = stack[0];
if(top === undefined || nums2[i] < top) { // 空队列,或者栈顶元素大于要入队的元素。
stack.unshift(nums2[i]);
} else {
while( nums2[i] > top && stack.length > 0 ) { // 如果栈顶元素小于待入栈元素,说明下一个最大的数就是待入栈元素)
// 栈顶元素出栈
stack.shift();
// 记录栈顶元素的下一个更大的元素
nextMap[top] = nums2[i];
// 更新栈顶元素
top = stack[0]
}
// 新的更大的元素入栈
stack.unshift(nums2[i]);
}
}
for(var i = 0; i < nums1.length;i++) {
const greaterNum = nextMap[nums1[i]]
res.push(greaterNum !== undefined? greaterNum : -1);
}
return res;
};