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

【算法300】:栈02

921. 使括号有效的最少添加

只有满足下面几点之一,括号字符串才是有效的:

它是一个空字符串,或者
它可以被写成 AB (A 与 B 连接), 其中 A 和 B 都是有效字符串,或者
它可以被写作 (A),其中 A 是有效字符串。
给定一个括号字符串 s ,在每一次操作中,你都可以在字符串的任何位置插入一个括号

例如,如果 s = “()))” ,你可以插入一个开始括号为 “(()))” 或结束括号为 “())))” 。
返回 为使结果字符串 s 有效而必须添加的最少括号数。

class Solution {
public:int minAddToMakeValid(string s) {// 当成一个栈的模拟题目来做stack<char> sk;for(auto ch : s){if(ch == '(') sk.push(ch);else {if(sk.size() && sk.top() == '(') sk.pop();else sk.push(ch);}}return sk.size();}
};

946. 验证栈序列

给定 pushed 和 popped 两个序列,每个序列中的 值都不重复,只有当它们可能是在最初空栈上进行的推入 push 和弹出 pop 操作序列的结果时,返回 true;否则,返回 false 。

示例 1:

输入:pushed = [1,2,3,4,5], popped = [4,5,3,2,1]
输出:true
解释:我们可以按以下顺序执行:
push(1), push(2), push(3), push(4), pop() -> 4,
push(5), pop() -> 5, pop() -> 3, pop() -> 2, pop() -> 1
示例 2:

输入:pushed = [1,2,3,4,5], popped = [4,3,5,1,2]
输出:false
解释:1 不能在 2 之前弹出。

class Solution {
public:bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {// 我们还是直接进行模拟stack<int> sk;int cur = 0;for(auto i : pushed){sk.push(i);while(!sk.empty() && sk.top() == popped[cur]) {sk.pop();++cur;}}return sk.empty();}
};

1190. 反转每对括号间的子串

给出一个字符串 s(仅含有小写英文字母和括号)。

请你按照从括号内到外的顺序,逐层反转每对匹配括号中的字符串,并返回最终的结果。

注意,您的结果中 不应 包含任何括号

class Solution {
public:string reverseParentheses(string s) {string res;stack<string> sk;for(auto ch : s){if(ch == '('){sk.push(res);res = "";}else if(ch == ')'){reverse(res.begin(), res.end());res = sk.top() + res;sk.pop();}else res.push_back(ch);}    return res;}
};

1209. 删除字符串中的所有相邻重复项 II

给你一个字符串 s,「k 倍重复项删除操作」将会从 s 中选择 k 个相邻且相等的字母,并删除它们,使被删去的字符串的左侧和右侧连在一起。

你需要对 s 重复进行无限次这样的删除操作,直到无法继续为止。

在执行完所有删除操作后,返回最终得到的字符串。

本题答案保证唯一。

class Solution {
public:string removeDuplicates(string s, int k) {stack<pair<char,int>> sk;int count = 0;for(auto ch : s){if(!sk.empty() && sk.top().first == ch){count = sk.top().second + 1;sk.push({ch, count});}else {count = 1;sk.push({ch, count});}if(count == k){auto tmp = k;while(tmp--) sk.pop();}}std::string res;while(!sk.empty()){res.push_back(sk.top().first);sk.pop();}reverse(res.begin(), res.end());return res;}
};

84. 柱状图中最大的矩形 (经典的单调栈问题,hard)

给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。

求在该柱状图中,能够勾勒出来的矩形的最大面积。

思路:

这道题目的思路可以参考每日温度这道题目,如果通过暴力的方式,我们将高度作为第一层遍历, 假设height[i]是当前矩形的最低高度,然后我们需要找到左右的最近的< heights[i]的位置, 这个时候我们就可以通过单调栈进行优化,通过两次遍历我们可以找到,每个位置对应的left, right, 为了方便计算,假定-1 和 n位置为负无穷。

class Solution {
public:int largestRectangleArea(vector<int>& heights) {// 通过单调栈的思路来进行解答vector<int> left(heights.size());auto right = left;stack<pair<int,int>> sk;// 填充left arrayfor(int i = 0;i < heights.size();i++){auto value = heights[i];if(sk.size() && value > sk.top().first){left[i] = sk.top().second;sk.push({value, i});}else // size() == 0 || value <= top.first;{while(sk.size() && value <= sk.top().first)sk.pop();left[i] = sk.empty() ? -1 : sk.top().second;sk.push({value, i});}}// 填充right arraysk = stack<pair<int,int>>();for(int i = 0;i < heights.size();i++){auto value = heights[i];while(sk.size() && value < sk.top().first){right[sk.top().second] = i;sk.pop();}sk.push({ value, i });}while(sk.size()){right[sk.top().second] = heights.size();sk.pop();}// 计算最终的结果// // debug// int maxValue = 0;// std::cout << "left array:" << std::endl;// for(auto i : left) std::cout << i << " ";// std::cout << std::endl;// std::cout << "right array: " << std::endl;// for(auto i : right) std::cout << i << " ";// std::cout << std::endl; // //int maxValue = 0;for(int i = 0;i < left.size();i++)maxValue = max(maxValue, heights[i] * (right[i] - left[i] - 1));return maxValue;}
};

316. 去除重复字母

给你一个字符串 s ,请你去除字符串中重复的字母,使得每个字母只出现一次。需保证 返回结果的字典序最小(要求不能打乱其他字符的相对位置)。

class Solution {
public:// 通过hash去重string removeDuplicateLetters(string s) {int Cnt[129] = { 0 };for(auto e : s)Cnt[e]++;bool used[129] = { false };vector<char> res;for(auto e : s){Cnt[e]--;if(used[e]) continue;while(res.size() && res.back() > e && Cnt[res.back()]){used[res.back()] = false;res.pop_back();}res.push_back(e);used[e] = true;}std::string ret;std::copy(res.begin(), res.end(), std::back_inserter(ret));return ret;}
};

85. 最大矩形

给定一个仅包含 0 和 1 、大小为 rows x cols 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。

示例 1:

输入:matrix = [[“1”,“0”,“1”,“0”,“0”],[“1”,“0”,“1”,“1”,“1”],[“1”,“1”,“1”,“1”,“1”],[“1”,“0”,“0”,“1”,“0”]]
输出:6
解释:最大矩形如上图所示。
示例 2:

输入:matrix = [[“0”]]
输出:0
示例 3:

输入:matrix = [[“1”]]
输出:1

提示:

rows == matrix.length
cols == matrix[0].length
1 <= row, cols <= 200
matrix[i][j] 为 ‘0’ 或 ‘1’

class Solution {
public:// 84题通过单调栈实现的int largestRectangleArea(vector<int>& heights) {// 通过单调栈的思路来进行解答vector<int> left(heights.size());auto right = left;stack<pair<int,int>> sk;// 填充left arrayfor(int i = 0;i < heights.size();i++){auto value = heights[i];if(sk.size() && value > sk.top().first){left[i] = sk.top().second;sk.push({value, i});}else // size() == 0 || value <= top.first;{while(sk.size() && value <= sk.top().first)sk.pop();left[i] = sk.empty() ? -1 : sk.top().second;sk.push({value, i});}}// 填充right arraysk = stack<pair<int,int>>();for(int i = 0;i < heights.size();i++){auto value = heights[i];while(sk.size() && value < sk.top().first){right[sk.top().second] = i;sk.pop();}sk.push({ value, i });}while(sk.size()){right[sk.top().second] = heights.size();sk.pop();}// 计算最终的结果// // debug// int maxValue = 0;// std::cout << "left array:" << std::endl;// for(auto i : left) std::cout << i << " ";// std::cout << std::endl;// std::cout << "right array: " << std::endl;// for(auto i : right) std::cout << i << " ";// std::cout << std::endl; // //int maxValue = 0;for(int i = 0;i < left.size();i++)maxValue = max(maxValue, heights[i] * (right[i] - left[i] - 1));return maxValue;}int maximalRectangle(vector<vector<char>>& matrix) {int m = matrix.size(), n = matrix[0].size();vector<int> heights(n, 0);int maxValue = 0;for(int i = 0;i < m;i++){for(int j = 0;j < n;j++){if(matrix[i][j] == '1')heights[j]++;else heights[j] = 0;}maxValue = std::max(maxValue, largestRectangleArea(heights));}return maxValue;}
};
http://www.dtcms.com/a/289584.html

相关文章:

  • Day25| 491.递增子序列、46.全排列、47.全排列 II、回溯总结
  • JAVA面试宝典 -《API设计:RESTful 与 GraphQL 对比实践》
  • Error: You don‘t have permission to access that port.当端口被莫名占用时,kill它!
  • G1回收器垃圾回收过程
  • 30天打牢数模基础-卷积神经网络讲解
  • 将来职业从事股票市场投资工作,应该做什么?
  • Python趣味算法:借书方案知多少 | 排列组合穷举法详解
  • DeepSeek+LoRA微调大模型实战
  • 【机器学习深度学习】魔塔社区模型后缀全解析:Base、Chat、Instruct、Bit、Distill背后的技术密码
  • 【Java多线程-----复习】
  • InfluxDB 核心概念与发展历程全景解读(二)
  • AtCoder Beginner Contest 415
  • 数控调压BUCK电路 —— 基于TPS56637(TI)
  • 乐观锁实现原理笔记
  • Android activity与service通信的三种方法
  • 30天打牢数模基础-K均值聚类
  • (DINO)Emerging Properties in Self-Supervised Vision Transformers论文精读(逐段解析)
  • (苍穹外卖)暑假学习理解P2
  • 从零搭建智能搜索代理:LangGraph + 实时搜索 + PDF导出完整项目实战
  • [C/C++安全编程]_[中级]_[如何安全使用循环语句]
  • k8s:离线部署存在的相关问题
  • 近期工作感想:职业规划篇
  • 【单片机外部中断实验修改动态数码管0-99】2022-5-22
  • Linux文件系统三要素:块划分、分区管理与inode结构解析
  • 本地部署开源离线内容浏览器 Kiwix 并实现外部访问( Windows 版本)
  • 【Java新特性】Java 21 新特性全解析
  • CSS面试题及详细答案140道之(121-140)
  • 快速理解LLM的temperature和top_p参数
  • 设备健康管理实施案例:从技术架构到落地效果的全栈解析
  • MCP实战案例|Trae2.0 一键创建旅行助手并一键部署EdgeOne