一、题目描述:
给你两个 没有重复元素 的数组 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 。
提示:
1 <= nums1.length <= nums2.length <= 1000
0 <= nums1[i], nums2[i] <= 104
nums1和nums2中所有整数 互不相同
nums1 中的所有整数同样出现在 nums2 中
二、思路分析:
从这道题的条件可知nums1是nums2的子集,所以只需要在得知nums2中所有元素的下一个更大元素,就可以从这个结果中得到nums1中每个元素对应的下一个更大值。
-
先不考虑nums1,对nums2进行遍历。
-
确认遍历范围,每个目标元素的下一个更大元素, 从目标元素的后一个元素开始到数组最后一个元素。
nums2.slice(targetIndex + 1, nums2.length - 1) -
通过辅助栈,记录遍历过程中还未匹配到下一个更大元素的元素。
-
遍历nums1, 获取每个元素对应的下一个更大元素。
其他优化:在进行其他nums2遍历的时候,可以将元素和对应的结果通过键值对的形式进行存储,方便第四步获取最后结果时可以更加快速。
比如当 nums1 = [4,1,2], nums2=[1,3,4,2]
当前元素:
target, 辅助栈stack:
若没有前一个元素,也就是无对比对象,进栈
若比前一个元素小或者stack.top(),进栈
(注意:此时存入栈中的信息的元素对应的索引,因为只存元素值无法确认这个元素在nums2中的位置)
若target > stack.top(),那么意味着前一个元素找到了下一个目标元素
栈的进出情况如下:
三、AC 代码:
/**
* @param {number[]} nums1
* @param {number[]} nums2
* @return {number[]}
*/
var nextGreaterElement = function(nums1, nums2) {
const map = new Map();
const s = [];
for(let i = 0; i < nums2.length; i++) {
while(s.length && nums2[i] > nums2[s.slice(-1)]) {
map.set(nums2[s.pop()], nums2[i]);
}
s.push(i);
}
return nums1.map(i => map.get(i) || -1);
};
四、总结:
善用辅助栈来存储一些过程类的信息。Map结构也是个好东西,通过key直接获取value,比遍历数组的效率要高很多。
本文正在参与「掘金 2021 春招闯关活动」, 点击查看 活动详情