JavaScript算法每日一题下一个更大元素I

每日一题:每天一个新挑战;
循序渐进:从易到难,扎实掌握;
系统分类:按数据结构分类,有助于构建知识框架;
丰富题量:100 道精选题,覆盖简单/中等/困难难度。

nums1 中数字 x下一个更大元素 是指 xnums2 中对应位置 右侧第一个 比 x 大的元素。

给你两个 没有重复元素 的数组 nums1nums2 ,下标从 0 开始计数,其中nums1nums2 的子集。

对于每个 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 <= 1000
  • 0 <= nums1[i], nums2[i] <= 10^4
  • nums1nums2中所有整数 互不相同
  • nums1 中的所有整数同样出现在 nums2

进阶:你可以设计一个时间复杂度为 O(nums1.length + nums2.length) 的解决方案吗?

代码卡片

JavaScript算法每日一题下一个更大元素I

题目解析

这个问题要求找到数组 nums1 中每个元素在数组 nums2 中的下一个更大元素。题目提供了两个数组 nums1nums2,并且 nums1nums2 的子集。我们需要遍历 nums1 中的每个元素,找到它在 nums2 中的位置,然后从该位置开始寻找第一个比它大的元素。如果找不到更大的元素,则返回 -1。

方法一:暴力解法

  1. 对于 nums1 中的每一个元素,首先找到它在 nums2 中的对应位置。
  2. 从该位置开始向右遍历 nums2,寻找第一个比当前元素大的数。
  3. 如果找到,记录下这个数;如果找不到,记录为 -1。

这种方法的时间复杂度是 O(nums1.length * nums2.length),适用于小规模的输入。

  • 时间复杂度:O(nums1.length * nums2.length)。对于 nums1 中的每一个元素,我们都需要在 nums2 中进行一次遍历。
  • 空间复杂度:O(1),除了存储结果的数组外,不需要额外的空间。
var nextGreaterElement = function (nums1, nums2) {
    const ans = [];
    for (let num of nums1) {
        let found = false;
        let greater = -1;
        for (let i = nums2.indexOf(num) + 1; i < nums2.length; i++) {
            if (nums2[i] > num) {
                greater = nums2[i];
                break;
            }
        }
        ans.push(greater);
    }
    return ans;
}

方法二:使用单调栈的优化方法

具体来说:

  1. 从右往左遍历 nums2,使用栈来记录可能的下一个更大元素。
  2. 对于每个元素,如果栈顶元素小于等于当前元素,则弹出栈顶,直到找到一个比当前元素大的元素或栈为空。
  3. 记录当前元素的下一个更大元素(如果存在)。
  4. 然后处理 nums1 中的元素,直接查找预处理后的结果。
  • 时间复杂度:O(nums1.length + nums2.length)。遍历 nums2O(nums2.length),构建结果数组是 O(nums1.length)
  • 空间复杂度:O(nums2.length),用于存储栈和哈希映射。
var nextGreaterElement = function (nums1, nums2) {
    const nextGreaterMap = new Map();
    const stack = [];

    for (let i = nums2.length - 1; i >= 0; i--) {
        const num = nums2[i];
        while (stack.length > 0 && stack[stack.length - 1] <= num) {
            stack.pop();
        }
        nextGreaterMap.set(num, stack.length > 0 ? stack[stack.length - 1] : -1);
        stack.push(num);
    }

    return nums1.map(num => nextGreaterMap.get(num));
}

总结

使用单调栈的方法可以更高效地解决问题,尤其适合较大规模的输入。这种方法利用栈结构保存候选值,避免了暴力解法中重复的遍历,从而实现了线性时间复杂度。

发布者:股市刺客,转载请注明出处:https://www.95sca.cn/archives/288992
站内所有文章皆来自网络转载或读者投稿,请勿用于商业用途。如有侵权、不妥之处,请联系站长并出示版权证明以便删除。敬请谅解!

(0)
股市刺客的头像股市刺客
上一篇 3小时前
下一篇 3小时前

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注