首页 > 其他分享 >单调栈复习01_230617

单调栈复习01_230617

时间:2023-06-17 22:55:18浏览次数:65  
标签:230617 01 复习 int top st push height size

主要关注栈内元素放置的是什么

栈头-栈尾递增还是递减,寻找右侧最大元素,则栈内元素递增;

例如Leetcode的每日温度,实则寻找右侧首个大于自身的元素位置,则栈内元素为下标、栈内元素逐渐增大,如果遍历到的元素小于栈顶元素则入栈,否则出栈

主要逻辑如下:


    vector<int> dailyTemperatures(vector<int>& temperatures) {
       //寻找右侧最大元素 栈顶-栈底 递增
       int size = temperatures.size();
       stack<int>st;
       vector<int>ans(size,0);
       st.push(0);
        for (int i = 1; i < size; ++i) {
            while(!st.empty() && temperatures[i] > temperatures[st.top()]){
               ans[st.top()] = i - st.top();
                st.pop();
//                st.push(i);
            }
            st.push(i);
        }
        return ans;
    }

其次,接雨水与最大矩形面积则是寻找左右两侧最大值,然后考虑木桶效应,找完最大值之后进行比较选择较小者。
主要逻辑如下:
接雨水:

   int trap(vector<int>& height) {
        stack<int>st;
        st.push(0);
        int sum = 0;
        for (int i = 1; i < height.size(); ++i) {
            //栈中元素为vector的下标
            //栈中元素从栈头到栈尾关系为从小到大

            while (!st.empty() && height[st.top()] < height[i]){
                int mid =  st.top();
                st.pop();
                if (!st.empty()){
                    int w = i - st.top() - 1;
                    int h = min(height[st.top()],height[i]) - height[mid];
                    sum += h * w;
                }
            }
            st.push(i);
        }
        return sum;
    }

最大柱形图面积:

int largestRectangleArea(vector<int>& height) {       
   height.insert(height.begin(),0);
        stack<int> st;
        int ans = 0;
        st.push(0);
        for (int i = 1; i < height.size(); ++i) {
            if (height[i] > height[st.top()]){
                st.push(i);
            } else if (height[i] == height[st.top()]){
                st.pop();
                st.push(i);
            } else{
                while (!st.empty() && height[i] < height[st.top()]){
                    int mid =st.top();
                    st.pop();
                    if (!st.empty()){
                        int h = height[mid];//min(height[i], height[st.top()]) -
                        int w = i - st.top() - 1;
                        ans = max(ans, h * w);
                    }
                }
                st.push(i);
            }
        }
        return ans;
    }

双指针法也可以解决柱形图和接雨水问题:

柱形图面积:

//双指针法
    int largestRectangleArea(vector<int>& height) {
        /*int size = height.size();
        vector<int>minLeftIndex(size,0);
        vector<int>minRightIndex(size,0);
        minLeftIndex[0] = -1;
        for (int i = 1; i < size; ++i) {
            int t = i - 1;
            //寻找左侧第一个小于本柱子的下标
            while(t >= 0 && height[t] >= height[i]) t =minLeftIndex[t];
            minLeftIndex[i] = t;
        }
        for (const auto &item: minLeftIndex)
            cout << "item: " << item ;
        cout << endl;
        minRightIndex[size - 1] = size;
        for (int i = size - 2; i >=0; i--) {
            int t = i + 1;
            //寻找右侧第一个小于本柱子的下标
            while(t < size && height[t] >= height[i]) t = minRightIndex[t];//此处为何取到=
            minRightIndex[i] = t;
        }

        for (const auto &item: minRightIndex)
            cout << "item: " << item ;
        int result= 0;
        for (int i = 0; i < size; ++i) {
            int sum = height[i] * (minRightIndex[i] - minLeftIndex[i] - 1);
            result = max(sum,result);
        }
        return result;
    }

接雨水:

//双指针优化
       int size = height.size();
        vector<int> maxLeftHeight(size);
        vector<int> maxRightHeight(size);
        maxLeftHeight[0] = height[0];
        for (int i = 1; i < size; ++i) {
            maxLeftHeight[i] = max(maxLeftHeight[i - 1],height[i]);
        }
        maxRightHeight[size - 1] = height[size - 1];
        for (int i = size - 2; i >= 0 ; i--) {
            maxRightHeight[i] = max(maxRightHeight[i + 1],height[i]);
        }

        int sum = 0;
        for (int i = 0; i < size; ++i) {
            int count = min(maxLeftHeight[i],maxRightHeight[i]) - height[i];
            if (count > 0) {
                cout << count << endl;
                sum += count;
            }
        }
        return sum;



标签:230617,01,复习,int,top,st,push,height,size
From: https://www.cnblogs.com/asupersource-tech/p/17488437.html

相关文章

  • 路径之谜(DFS)-2016年蓝桥杯国赛
    路径之谜-2016年国赛1、题目描述2、解题思路3、代码实现1、题目描述  小明冒充X星球的骑士,进入了一个奇怪的城堡。  城堡里边什么都没有,只有方形石头铺成的地面。  假设城堡地面是n×n*个方格。如下图所示。  按习俗,骑士要从西北角走到东南角。可以横向或纵向移动,但......
  • react经典面试题解析--持续更新--day01
    一、类组件和函数组件的区别(面试常考)简单理解(所有同学都要掌握)1、类组件有生命周期,函数组件没有2、类组件需要继承Class,函数组件不需要3、类组件可以获取实例化的this,并且基于this做各种操作,函数组件不行4、类组件内部可以定义并维护state,函数组件都称为无状态了,那肯定......
  • 算法复习
    选择题考点:时间复杂性从低到高的顺序是?问题:有一个算法,它的时间复杂性T(n)的递归定义如下,问T(n)是?下面哪些内容不是算法设计之前要完成的内容?使用何种计算机语言设计程序在算法设计与分析过程中,有算法设计,算法的正确性证明,算法的复杂性分析,程序设计等几个重要步骤,下......
  • P4305 [JLOI2011] 不重复数字
    思路:新建一个数组或者哈希表,检查新输入的元素是否在里面,如果在就pass,如果不在就作为新元素存进去,最后输出即可数组实现:60分#include<bits/stdc++.h>usingnamespacestd;intmain(){intnum;cin>>num;for(num;num>=1;num--){intn,x;cin>>n;......
  • 服务器内存跑满是什么原因造成的 43.248.101.x
    相信大家在使用服务器的时候会有出现内存使用率比较高的情况,那接下来小编跟大家说下到底是哪些原因导致内存不足:一、应用程序池应用程序池有一个默认回收的时间,到了这个时间就会自动释放内存,这个时间一般是1740分钟,而这种程度的时间可能会导致应用程序池无法及时释放内存,从而出现内......
  • [GXYCTF2019]Ping Ping Ping 1
    先尝试输入ip=127.0.0.1发现啥也没有再次在后面输入ls查看文件发现有两个文件Cat一下发现有空格过滤进行空格绕过$(IFS)(?ip=127.0.0.1;cat$IFS$1flag.php)发现符合也进行了过滤尝试进行拼接flag?ip=127.0.0.1;a=g;cat$IFS$1fla$a.php发现flag......
  • [极客大挑战 2019]Havefun
    [极客大挑战2019]Havefunf12查看代码,发现进行审计:$cat=$_GET['cat'];#get一个变量名字为cat​echo$cat;#显示cat​if($cat=='dog')#判断cat是否为dog{​echo'Syc{cat_cat_cat_cat}';#如果cat=dog那么输出(初次判断{}中为flag因为有{})}解法:get一个cat变......
  • [极客大挑战2019]EasySQL** 1
    [极客大挑战2019]EasySQL**1得到flag。万能密码"or"a"="a')or('a'='aor1=1--'or1=1--a'or'1=1--"or1=1--'or'a'='a"or"="a'='a'or''=......
  • HIMA F 8650X 中央模块 PN:98 4865065 REV,01
    HIMAF8650X中央模块PN:984865065REV,01HIMAF8650X中央模块PN:984865065REV,01 多任务机制其实在单一CPU的情况下,是不存在真正的多任务机制的,存在的只有不同的任务轮流使用CPU,所以本质上还是单任务的。但由于CPU执行速度非常快,加上任务切换十分频繁并且切......
  • AGC019F Yes or No
    题意有\(N+M\)个问题,其中有\(N\)个问题的答案是YES,\(M\)个问题的答案是NO。当你回答一个问题之后,会知道这个问题的答案,求最优策略下期望对多少。答案对\(998244353\)取模。数据范围:\(1\leN,M\le5\times10^5\)。题解首先每次必定去猜那个个数更多的问题。用点\((......