二刷代码随想录——单调栈day58

本文介绍了单调栈在编程竞赛中的应用,包括如何解决739.每日温度和496.下一个更大元素I问题。通过单调栈的单调性特点,实现在一次遍历中找到相应元素的后续操作位置。
摘要由CSDN通过智能技术生成


前言

一个本硕双非的小菜鸡,备战24年秋招,计划二刷完卡子哥的刷题计划,加油!
二刷决定精刷了,于是参加了卡子哥的刷题班,训练营为期60天,我一定能坚持下去,迎来两个月后的脱变的,加油!
推荐一手卡子哥的刷题网站,感谢卡子哥。代码随想录

单调栈知识点

代码随想录二刷即将结束,但是刷题大业仍未止。

单调栈是一种特殊的数据结构,它遵循单调性原则,即栈内元素要么单调递增,要么单调递减。单调栈的作用在于解决一些特定的问题,如找到一个元素在其序列中左边或右边第一个比其大或小的元素,或者用于解决一些编程竞赛中的题目。

单调栈的本质是空间换时间,因为在遍历的过程中需要用一个栈来记录右边第一个比当前元素高的元素,优点是整个数组只需要遍历一次。

单调栈的特点

单调栈的特点是,在维护栈的时候,如果要入栈的元素比栈顶元素大(对于单调递减栈)或小(对于单调递增栈),则将栈顶元素出栈,直到栈顶元素小于(对于单调递减栈)或大于(对于单调递增栈)当前要入栈的元素,然后将元素入栈。这个过程需要遍历一遍元素,因此时间复杂度为O(n)。

在使用单调栈的时候首先要明确如下几点:

单调栈里存放的元素是什么?
单调栈里只需要存放元素的下标i就可以了,如果需要使用对应的元素,直接T[i]就可以获取。

单调栈里元素是递增呢? 还是递减呢?

一、739. 每日温度

739. 每日温度
Note:控制实行单调栈

class Solution {
public:
    vector<int> dailyTemperatures(vector<int>& temperatures) {
        //递增栈
        stack<int> st;

        vector<int> result(temperatures.size(), 0);
        st.push(0);

        for (int i = 1; i < temperatures.size(); i++) {
            if (temperatures[i] < temperatures[st.top()])
                st.push(i);
            else if (temperatures[i] == temperatures[st.top()])
                st.push(i);
            else {
                while (!st.empty() && temperatures[i] > temperatures[st.top()]) {
                    result[st.top()] = i - st.top();
                    st.pop();
                }
                st.push(i);
            }
        }
        return result;
    }
};

二、496. 下一个更大元素 I

496. 下一个更大元素 I

Note:与上一题类似,都是单调栈解决问题

class Solution {
public:
    vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
        //单调栈
        stack<int> st;

        vector<int> result(nums1.size(), -1);
        if (nums1.size() == 0) return result;

        unordered_map<int, int> umap;
        for (int i = 0; i < nums1.size(); i++) {
            umap[nums1[i]] = i;
        }
        st.push(0);

        for (int i = 1; i < nums2.size(); i++) {
            if (nums2[i] < nums2[st.top()])
                st.push(i);
            else if (nums2[i] == nums2[st.top()])
                st.push(i);
            else {
                while (!st.empty() && nums2[i] > nums2[st.top()]) {
                    if (umap.count(nums2[st.top()]) > 0) {
                        int index = umap[nums2[st.top()]];
                        result[index] = nums2[i];
                    }
                    st.pop();
                }
                st.push(i);
            }
        }
        return result;
    }
};

总结

单调栈的实现可以基于数组,也可以基于链表,具体取决于问题的需求和上下文。在实现时,可以选择将元素值或元素的位置下标入栈,这取决于问题是否需要找到元素的位置信息。

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力找工作的小菜鸡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值