当前位置: 首页 > news >正文

单调队列与栈

一.题

1.

思路: 构建小压大的单调递减栈,对于每个栈的元素都进行处理并加到结果上

class Solution {
public:
    int sumSubarrayMins(vector<int>& arr) {
        int stk[10000000],top = 0;
        long long ans = 0;
        
        for(int i =0;i<arr.size();i++){
            while(top&&arr[i]<arr[stk[top-1]]){
                int cur = stk[--top];
                int l = top==0?-1:stk[top-1];
                ans = (ans+(long long)(cur-l)*(i-cur)*arr[cur])%(1000000007);
            }
            stk[top++] = i;
        }
        while(top){
            int cur = stk[--top];
            int l = top==0?-1:stk[top-1];
            ans = (ans+(long long)(cur-l)*(arr.size()-cur)*arr[cur])%(1000000007);
        }
        return ans;
    }
};

 2.

思路: 以每排都为一次底,然后压缩和第一题类似

#include <vector>
#include <string>
#include <algorithm>
#include <climits>

using namespace std;

class Solution {
public:
    int maximalRectangle(vector<string>& matrix) {
        if (matrix.empty() || matrix[0].empty()) return 0;

        int rows = matrix.size();
        int cols = matrix[0].size();
        vector<int> height(cols, 0); 
        int ans = 0; 

        for (int i = 0; i < rows; i++) {
       
            for (int j = 0; j < cols; j++) {
                if (matrix[i][j] == '1') height[j] += 1;  
                else height[j] = 0; 
            }

            int stk[cols + 2], top = 0;
            stk[top++] = -1; 

            for (int j = 0; j <= cols; j++) {
                while (top > 1 && (j == cols || height[stk[top - 1]] >= height[j])) {
                    int curHeight = height[stk[--top]]; 
                    int width = j - stk[top - 1] - 1; 
                    int area = curHeight * width; 
                    ans = max(ans, area); 
                }
                stk[top++] = j; 
            }
        }

        return ans;
    }
};

3.

思路:用单调栈收集每个可能是低点的位置,使得栈严格小压大,单调递增,然后方向遍历全部的元素与栈中元素比较来找距离最远的坡

class Solution {
public:
    int maxWidthRamp(vector<int>& nums) {
        
        int stk[50050],top = 0;
        int ans = 0;
        stk[top++] = 0;

        for(int i =0;i<nums.size();i++){
           if(nums[i]<nums[stk[top-1]])stk[top++] = i;
        }

        for(int i = nums.size()-1;i>=0;i--){
            while(top&&nums[i]>=nums[stk[top-1]]){
                int cur = stk[--top];
                int temp_l = i - cur;
                ans = max(ans,temp_l);
            }
        }
        return ans;
    }
};

4.

思路:还是利用单调栈的特性,大压小,开头从栈底部开始,同时用一个数组标记是不是在栈中

#include <string>
#include <vector>

using namespace std;

class Solution {
public:
    string removeDuplicateLetters(string s) {
        int counts[26] = {0}; 
        bool inStack[26] = {false}; 
        char stk[10005];
        int top = 0; 

        for (char ch : s) 
            counts[ch - 'a']++;

        for (char ch : s) {
            if (inStack[ch - 'a']) {
                counts[ch - 'a']--;
                continue;
            }
            while (top > 0 && stk[top - 1] > ch && counts[stk[top - 1] - 'a'] > 0) {
                inStack[stk[top - 1] - 'a'] = false; 
                top--; 
            }

            stk[top++] = ch;
            inStack[ch - 'a'] = true; 
            counts[ch - 'a']--; 
        }

        string result;
        for (int i = 0; i < top; i++) result += stk[i];
        return result;
    }
};

 5.

思路:因为,鱼是吃右边的更小的鱼,所以方向遍历后往前,因为小不能吃大,为小压大,在用个cnt数组统计每条鱼进行的场数,用max来求最大值

#include <iostream>
#include <vector>
#include <stack>
using namespace std;

int main() {
   int n,ans = -1;
   cin>>n;

   vector<int> fish(n);
   for(int i = 0; i < n; i++)cin>>fish[i];

   vector<int> cnt(n,0);
   stack<int> stk;

   for(int i = n-1; i >= 0; i--){
       while(!stk.empty() && fish[i]>fish[stk.top()]){
           int cur = stk.top();stk.pop();
           cnt[i] = max(cnt[i]+1,cnt[cur]);  
        }
        stk.push(i);
        ans = max(ans,cnt[i]);
   }
   
   cout<<ans;
   return 0;
}

 6.算法竞赛进阶指南

思路:模拟过程即可

#include <iostream>
#include <vector>
#include <stack>
#include <algorithm>
#include<queue>

using namespace std;

int main() {
    int cnt[14];
    int time[14];
    vector<vector<char>>tt(14, vector<char>(5, 0));

    for (int i = 1; i <= 13; i++){
        cnt[i] = 4; time[i] = 0;
        for (int j = 1; j <= 4; j++)
            cin >> tt[i][j];
    }
    cnt[13] = 1;
        
    while (cnt[13] <= 4) {
        char temp = tt[13][cnt[13]++];
        if (temp == 'K') continue;

        while (temp != 'K') {
            int num = 0;
            if (temp == 'A')num = 1;
            else if (temp == '0')num = 10;
            else if (temp == 'J')num = 11;
            else if (temp == 'Q')num = 12;
            else num = temp - '0';
   
            time[num]++;
            if (cnt[num] == 0)break;
            temp = tt[num][cnt[num]--];
        }
    }

    int ans = 0;
    for (int i = 1; i <= 12; i++) {
        if (time[i] == 4)ans++;
    }
    cout << ans;
    return 0;
}

 

相关文章:

  • 如何取消WPS Excel文件密码
  • 2.14学习总结
  • 【论文阅读】Revisiting the Assumption of Latent Separability for Backdoor Defenses
  • 用 Python 实现 DeepSeek R1 本地化部署
  • Prompt 工程优化方
  • 一区IEEE Trans|特征模态分解FMD,一维数据分解新方法-matlab免费代码
  • 自有证书的rancher集群使用rke部署k8s集群异常
  • C++ STL 容器
  • Visual Studio 编译 onnxruntime 1.14.1 更低版本兼容Win7
  • IOTDB安装部署
  • 【linux】文件与目录命令 - ln
  • 网络安全 | 网络攻击介绍
  • linux 安装nginx
  • python 指定目录位置,查找指定扩展名的文件是否有指定的关键字
  • # 解析Excel文件:处理Excel xlsx file not supported错误 [特殊字符]
  • 【Mastering Vim 2_03】第二章:精通 Vim 高级技巧之:编辑与浏览技巧 + 第三方增强插件的用法
  • DeepSeek从入门到精通:提示词设计的系统化指南
  • 08模拟法 + 技巧 + 数学 + 缓存(D4_缓存)
  • Postman配置环境变量(超详细的)
  • JavaScript 发起网络请求 axios、fetch、async / await
  • 网站后台管理员做链接/新闻平台发布
  • 网站建设优化开发公司哪家好/app推广拉新
  • 网站建设推广策划/怎么推广一个平台
  • 做直播券的网站有多少钱/大数据精准营销的策略
  • 法律建设网站/怎么创建网页链接
  • 如何做商城网站/拼多多代运营公司十大排名