【leetcode】496. 下一个更大元素 I|刷题打卡

239 阅读3分钟

一、题目描述:

原题地址

给你两个 没有重复元素 的数组 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中每个元素对应的下一个更大值。

  1. 先不考虑nums1,对nums2进行遍历

  2. 确认遍历范围,每个目标元素的下一个更大元素, 从目标元素的后一个元素开始到数组最后一个元素。nums2.slice(targetIndex + 1, nums2.length - 1)

  3. 通过辅助栈,记录遍历过程中还未匹配到下一个更大元素的元素。

  4. 遍历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 春招闯关活动」, 点击查看 活动详情