【前端er每日算法】单调栈两题

79 阅读1分钟

题目一 739. 每日温度

给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer ,其中 answer[i] 是指对于第 i 天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0 来代替。

思路

单调栈记录之前访问过的元素,找右侧第一个比自己大的元素,需要单调递增的单调栈。

  • 首先进入第一个元素
  • 比较栈顶元素和当前元素的大小:
    1. 如果当前元素小于等于栈顶元素,符合单调递增的条件,则直接入栈
    2. 如果当前元素大于栈顶元素,则说明栈顶元素找到了第一个比自己大的元素,要弹出栈顶元素,并且记录栈顶元素的结果为 当前元素索引减去栈顶元素索引,如果当前元素还是大于下一个栈顶元素,则继续重复上述过程,直至遇到比它小的元素或者为空
var dailyTemperatures = function(temperatures) {
    const len = temperatures.length;
    const stack = [0];
    let result = new Array(len).fill(0);
    for (let i = 1; i < len; i++) {
        let top = temperatures[stack[stack.length - 1]];
        const cur = temperatures[i];
        if (cur <= top) {
            stack.push(i);
        } else {
            while (cur > top && stack.length) {
                // 弹出栈顶元素,记录结果
                const topIndex = stack.pop();
                result[topIndex] = i - topIndex;
                top = temperatures[stack[stack.length - 1]]; 
            }
            stack.push(i);
        }
    }
    return result;
};

题目二 . 下一个更大元素 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] 是如上所述的 下一个更大元素 。

思路

和题目一类似,但是比较绕,在nums2中找nums1的元素的第一个大的元素。

  1. 结果应该和nums1大小相同的数组,初始化为-1,并且建一个nums1的map。
  2. 用nums2构造单调栈,构造过程和题目一类似,构造单调递增的单调栈,栈里存放元素值
    1. 如果当前元素大于栈顶元素,不断出栈栈顶元素,这个时候判断如果出栈的栈顶元素是在nums1中的,则记录结果,否则不需要记录结果,根据map找到result中的索引,赋值为cur
    2. 否则还是入栈
var nextGreaterElement = function(nums1, nums2) {
    const len1 = nums1.length;
    const result = new Array(len1).fill(-1);
    let map = {};
    for (let i = 0; i < nums1.length; i++) {
        map[nums1[i]] = i;
    }
    let stack = [nums2[0]];
    for (let i = 1; i < nums2.length; i++) {
        const cur = nums2[i];
        let top = stack[stack.length - 1];
        while (cur > top && stack.length) {
            top = stack.pop();
            // 不在nums1中时,只需要弹出
            if (!top in map) {
                break;
            } else {
                result[map[top]] = cur;
            }
            top = stack[stack.length - 1];
        }
        stack.push(cur);
    }
    return result;
};