【用单调栈解决“下一个更大元素”】搞定股票、气温、数组跳跃!(JS + Python 双解)

56 阅读3分钟

🧠 引言

“下一个更大元素”是经典算法面试高频题目,典型题包括:

  • 每日温度(LeetCode 739)
  • 下一个更大元素(LeetCode 496)
  • 股票价格跨度(LeetCode 901)

它们的共同特征是:

找出右边第一个比当前元素大的值或索引

本篇我们将用单调栈技巧解决这类问题,并用 JavaScript 与 Python 双语代码,彻底吃透单调栈的核心原理与实战技巧。


📦 一、什么是单调栈?

单调栈是一种栈结构,栈中元素保持单调递增或递减的顺序。

常见应用:

  • 找“下一个更大/小”的值
  • 区间最值维护
  • 滑动窗口优化

🧪 Part 1:每日温度(LeetCode 739)

❓题目描述

给定一个整数数组 temperatures,表示每日气温。返回一个数组 answer,其中 answer[i] 是指 第 i 天后几天会变暖,若无更暖则为 0。

输入: [73,74,75,71,69,72,76,73]
输出: [1,1,4,2,1,1,0,0]

✅ 解法思路(单调递减栈)

  • 遍历温度数组
  • 栈中保存索引
  • 当前温度大于栈顶所对应温度 → 弹出,并计算间隔天数
  • 否则入栈等待配对

💻 JavaScript 实现

function dailyTemperatures(T) {
  const stack = [];
  const res = new Array(T.length).fill(0);

  for (let i = 0; i < T.length; i++) {
    while (stack.length && T[i] > T[stack[stack.length - 1]]) {
      const prev = stack.pop();
      res[prev] = i - prev;
    }
    stack.push(i);
  }

  return res;
}

🐍 Python 实现

def daily_temperatures(T):
    stack = []
    res = [0] * len(T)

    for i, temp in enumerate(T):
        while stack and temp > T[stack[-1]]:
            prev = stack.pop()
            res[prev] = i - prev
        stack.append(i)

    return res

🧪 Part 2:下一个更大元素(LeetCode 496)

❓题目描述

给定两个数组 nums1nums2,其中 nums1nums2 的子集,返回 nums1 中每个元素在 nums2 中的下一个更大值。如果没有,返回 -1。

输入: nums1 = [2,4], nums2 = [1,2,3,4]
输出: [3,-1]

✅ 解法思路

  • 单调栈预处理 nums2 中每个元素的“下一个更大值”
  • 用哈希表保存映射关系
  • 遍历 nums1 查表即可

💻 JavaScript 实现

function nextGreaterElement(nums1, nums2) {
  const stack = [];
  const map = {};

  for (let num of nums2) {
    while (stack.length && num > stack[stack.length - 1]) {
      map[stack.pop()] = num;
    }
    stack.push(num);
  }

  return nums1.map(n => map[n] ?? -1);
}

🐍 Python 实现

def next_greater_element(nums1, nums2):
    stack = []
    mapping = {}

    for num in nums2:
        while stack and num > stack[-1]:
            mapping[stack.pop()] = num
        stack.append(num)

    return [mapping.get(x, -1) for x in nums1]

⚠️ 常见错误总结

问题正确做法
栈中放值而不是索引(温度题)要用索引计算天数差值
遍历顺序写错(应左→右)从左到右维持递减栈
哈希表查不到值没默认 -1?? -1.get(x, -1)

🧩 拓展任务

  • 实现“下一个更小元素”
  • 改写为“左边第一个更大值”
  • 实现股票价格跨度(LeetCode 901)

📚 总结一句话

单调栈的本质是“等待配对”,一旦“遇强则出”,你就能在 O(n) 时间内解决“下一个更大”类问题!


📘 下一篇预告:

第15篇:【字符串双指针高频题】回文判断、最长无重复子串双解集!