[leetcode] 单调栈

本文总结单调栈算法。

原问题

学习一个算法,我们需要清楚的是:这个算法最原始的问题背景是什么样的?

下一个更小元素

给定一个数组 nums,返回每个元素的下一个更小的元素的下标 res,即 res[i] 记录的是 nums[i] 右端第一个比它小的元素的下标(不存在则为 -1 )。

例如 nums = [2,1,2,4,3],那么 res = [1, -1, -1, 4, -1] .

从左往右扫描数组,栈底到栈顶维持升序(不要求严格),当扫描当前元素 nums[i] = x 时,如果需要出栈(说明栈顶严格大于当前的 x ),那么 x 就是出栈元素的下一个更小元素。

vector<int> nextSmallerNumber(vector<int> &nums)
{
    int n = nums.size(), idx = -1;
    vector<int> res(n, -1);
    stack<int> stk;
    for (int i = 0; i < n; i++)
    {
        while (!stk.empty() && nums[stk.top()] > nums[i])
        {
            idx = stk.top(), stk.pop();
            res[idx] = i;
        }
        stk.emplace(i);
    }
    return res;
}

相关题目:

下一个更大元素

给定一个数组 nums,返回每个元素的下一个更大的元素的下标 res,即 res[i] 记录的是 nums[i] 右端第一个比它大的元素的下标(不存在则为 -1 )。

例如 nums = [2,1,2,4,3],那么 res = [3, 2, 3, -1, -1] .

从左往右扫描数组,栈底到栈顶维持降序(不要求严格),当扫描当前元素 nums[i] = x 时,如果需要出栈(说明栈顶严格小于当前的 x ),那么 x 就是出栈元素的下一个更大元素。

vector<int> nextGreaterNumber(vector<int> &&nums)
{
    int n = nums.size(), idx;
    vector<int> res(n, -1);
    stack<int> stk;
    for (int i = 0; i < n; i++)
    {
        while (!stk.empty() && nums[stk.top()] < nums[i])
        {
            idx = stk.top(), stk.pop();
            res[idx] = i;
        }
        stk.emplace(i);
    }
    return res;
}

类似题目:

Leetcode

下一个更大元素 I

题目:496. 下一个更大元素 I

题目保证 nums1nums2 的子集,首先在 nums2 先做一次「下一个更大」元素,使用一个哈希表记录结果。

然后扫描 nums1 ,把哈希表的结果按序填入数组 res 即可。

每次自己写出了最优解,并且官方也是同一思路,都会觉得好有成就感

上一篇:1516:消息的传递


下一篇:虚树的学习笔记