Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
一.题目
496. 下一个更大元素 I
nums1中数字x的 下一个更大元素 是指x在nums2中对应位置 右侧 的 第一个 比x****大的元素。 给你两个 没有重复元素 的数组nums1和nums2,下标从 0 开始计数,其中nums1是nums2的子集。 对于每个0 <= i < nums1.length,找出满足nums1[i] == nums2[j]的下标j,并且在nums2确定nums2[j]的 下一个更大元素 。如果不存在下一个更大元素,那么本次查询的答案是-1。
返回一个长度为 nums1.length 的数组 ans 作为答案,满足 **ans[i] **是如上所述的 下一个更大元素 。
示例 1:
输入:nums1 = [4,1,2], nums2 = [1,3,4,2].
输出:[-1,3,-1]
解释:nums1 中每个值的下一个更大元素如下所述:
- 4 ,用加粗斜体标识,nums2 = [1,3,4,2]。不存在下一个更大元素,所以答案是 -1 。
- 1 ,用加粗斜体标识,nums2 = [1,3,4,2]。下一个更大元素是 3 。
- 2 ,用加粗斜体标识,nums2 = [1,3,4,2]。不存在下一个更大元素,所以答案是 -1 。
示例 2:
输入:nums1 = [2,4], nums2 = [1,2,3,4].
输出:[3,-1]
解释:nums1 中每个值的下一个更大元素如下所述:
- 2 ,用加粗斜体标识,nums2 = [1,2,3,4]。下一个更大元素是 3 。
- 4 ,用加粗斜体标识,nums2 = [1,2,3,4]。不存在下一个更大元素,所以答案是 -1 。
提示:
1 <= nums1.length <= nums2.length <= 10000 <= nums1[i], nums2[i] <= 104nums1和nums2中所有整数 互不相同nums1中的所有整数同样出现在nums2中
二、思路分析:
这道题目是为数组中每个元素找到下一个更大元素的题目,所以我们需要用到单调栈的思路来求解问题,单调栈能够保证栈内元素是呈单调递增或者单调递减的栈结构。题目的要求刚好符合单调栈的需求,我们将数组从索引最大处进行栈的相关操作。
每次有元素入栈的时候,判断栈内是否有元素能够大于循环到的元素,将栈内比循环到的元素小的栈内元素全部弹出,完成之后将栈顶元素加入结果集中,如果栈内没有元素的时候就返回-1,循环结束后就能够得到所有数组元素的下一个较大值了。最后在根据nums1提供的元素对nums2进行匹配得到最终的结果集中。
三、代码:
/**
* @param {number[]} nums1
* @param {number[]} nums2
* @return {number[]}
*/
var nextGreaterElement = function (nums1, nums2) {
let res = []
let stack = []
let ans = []
for (let i = nums2.length - 1; i >= 0; i--) {
//把元素小的弹出去
while (stack.length && stack[stack.length - 1] < nums2[i]) {
stack.pop()
}
res[i] = stack.length ? stack[stack.length - 1] : -1
stack.push(nums2[i])
}
for (let i = 0; i < nums1.length; i++) {
ans[i] = res[nums2.indexOf(nums1[i])]
}
return ans
};
四、总结:
单调栈的操作特别适合求解这种寻找当前元素的下一个较大元素的问题,当然这个代码也有很多改良的地方,如把结果集的数组改成
Map的数据结构,之后只要让nums1的元素对应寻找Map中对应的键值就能够得到答案。