leetcode 经典栈相关题目(思路、方法、code)

本文记录了在LeetCode中使用栈解决经典问题的经验,包括20. 有效的括号、155. 最小栈、946. 验证栈序列等,通过栈结构分析解题思路,探讨如何运用单调栈解决相关问题。
摘要由CSDN通过智能技术生成

用于回顾数据结构与算法时刷题的一些经验记录
栈的题目还是稍微有些难度的

20. 有效的括号

给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串,判断字符串是否有效。

有效字符串需满足:

  • 左括号必须用相同类型的右括号闭合
  • 左括号必须以正确的顺序闭合
  • 注意空字符串可被认为是有效字符串
示例 1:
输入: "()"
输出: true
示例 2:
输入: "()[]{}"
输出: true

分析:判断括号是否有效是栈的最经典的运用之一。一个括号序列有效,需要对于每一个左括号都要有相应的右括号对应,还需要有相应的顺序才行。因此,如果一个右括号和之前输入的左括号相邻且匹配,则可以将其消去

因此在这里用栈作为数据结构解答该题,设置一个栈,如果加入的是一个左括号,则将其加入,如果加入的是一个右括号,则判断其是否能够与栈顶的括号对应,如果对应,则将栈顶 pop ,否则说明有错。因此经过对字符串的处理,如果最终栈不是空的,说明该字符串不是有效字符串。

class Solution {
   
public:
    bool isValid(string s) 
	{
   
    	stack<char> st;
		for(int i=0;i<s.size();i++)
		{
   
			if(s[i]=='('||s[i]=='{'||s[i]=='[') //左括号加入
				st.push(s[i]);
			else if(st.size()>0&&(s[i]==')'&&st.top()=='('||s[i]==']'&&st.top()=='['||s[i]=='}'&&st.top()=='{'))//右括号需要判断能否消除,不能消除即出错
				st.pop();
			else
				return false;	
		}
		if(st.size()==0)
			return true;
		return false;    
    }
};
155. 最小栈

设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈

push(x) —— 将元素 x 推入栈中。
pop() —— 删除栈顶的元素。
top() —— 获取栈顶元素。
getMin() —— 检索栈中的最小元素。

分析:通常的栈结构,push,pop,top均可以满足,但是 getMin()不能满足,能否增添一个变量用来标记最小值?如果有这个变量,则每次push元素我们都可以将元素进行比较,这样就可以O(1)获取最小元素。但是仔细想想,如果将最小元素pop了出来,那么现在的最下元素怎样标记?只能遍历获得,因此最终是O(n)获取最小元素。

故需要转换思路,怎样才能动态地存取最小元素?采用辅助栈。

使用两个栈,一个栈作为正常栈,另一个栈作为辅助栈。辅助栈用来存取当前的最小值,如果最小值更新,则压入新的最小值即可。

例子:

入栈 3 
|   |    |   |
|   |    |   |
|_3_|    |_3_|
stack  minStack

入栈 5 ,5大于minStack的栈顶,故不压入
|   |    |   |
| 5 |    |   |
|_3_|    |_3_|
stack  minStack

入栈 22小于最小值栈的栈顶,故将其入栈
| 2 |    |   |
| 5 |    | 2 |
|_3_|    |_3_|
stack  minStack

出栈 2,发现2是最小栈的栈顶,故minStack也出栈
|   |    |   |
| 5 |    |   |
|_3_|    |_3_|
stack  minStack

出栈 5,发现5不是最小栈的栈顶,因此minStack 不处理
|   |    |   |
|   |    |   |
|_3_|    |_3_|
stack  minStack

注意:如果入栈元素小于等于最小栈栈顶,则将其入栈,而非仅考虑小于,这是为了避免pop时候出错。(应对连续的相同元素)

class MinStack {
   
	private:
		stack<int> data;
		stack<int> min;
public:
    /** initialize your data structure here. */
    MinStack() 
	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值