LeetCode栈题目总结

更新中。。。

1.有效的括号

2.栈的压入、弹出序列

3.最小栈

4.用栈实现队列

5.下一个更大的数

1.有效的括号
题目描述:给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串,判断字符串是否有效。
有效字符串需满足:

*左括号必须用相同类型的右括号闭合
*左括号必须以正确的顺序闭合
*注意空字符串可被认为是有效字符串

示例 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;    
    }
};

2.栈的压入、弹出序列
题目描述:输入两个整数序列(pushed,poped), pushed表示栈的压入顺序,请判断poped是否为该栈的弹出顺序。 假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)

解题思路:这道题是栈系列的一道非常经典的题目,首先我们要借助一个辅助的栈,每次将pushed序列向辅助栈中加入一个元素,每加入一个元素,都要判断是否与当前popped序列当前的输出位置元素相同,如果相同,则将栈目前元素pop处,popped序列位置右移(注意这里是用一个循环,如果top的内容与popped序列位置内容一致则一直pop()。最终如果是合法序列的话最后的栈应该是空的,否则说明非法。

举例:
入栈1,2,3,4,5
出栈4,5,3,2,1
首先1入辅助栈,此时栈顶1≠4,继续入栈2
此时栈顶2≠4,继续入栈3
此时栈顶3≠4,继续入栈4
此时栈顶4=4,出栈4,poped序列向后一位,此时为5,,辅助栈里面是1,2,3
此时栈顶3≠5,继续入栈5
此时栈顶5=5,出栈5,poped序列向后一位,此时为3,,辅助栈里面是1,2,3
….
依次执行,最后辅助栈为空。如果不为空说明弹出序列不是该栈的弹出顺序。

class Solution
{
public :
    bool IsPopOrder ( vector < int > pushed , vector < int > poped )
    {
    //如果两个序列为空则返回false
        if (pushed . empty () || poped . empty ()) 
        return false ;
        stack < int > s ;
       
        //用于标识弹出序列的位置
        int j = 0 ;
        for ( int i = 0 ; i < pushed . size (); i ++) //扫描入栈序列
        {
            s . push ( pushed[ i ]); //push元素直到栈顶元素为pop序列中的元素
            while (! s . empty () && s.top() == pushed[j ]) //相等时,辅助栈出栈,弹出序列索引加一
            {
                s . pop ();
                j ++;
            }
        }
       
        return s . empty (); //如果为空,则说明入栈序列和出栈序列相匹配,为true,否则为false
    }
};

3.最小栈
题目描述:设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。

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

**解题思路:**用两个栈,一个存放数据,一个存放最小值。
举例:

入栈 3 
|   |    |   |
|   |    |   |
|_4_|    |_4_|
 s1        s2

入栈6 ,6大于s2的栈顶,故不压入
|   |    |   |
| 6 |    |   |
|_4_|    |_4_|
 s1        s2

入栈 22小于最小值栈的栈顶,故将其入栈
| 2 |    |   |
| 6 |    | 2 |
|_4_|    |_4_|
 s1        s2

出栈 2,发现2是最小栈的栈顶,故s2也出栈
|   |    |   |
| 6 |    |   |
|_4_|    |_4_|
 s1        s2

出栈 6,发现6不是最小栈的栈顶,因此s2 不处理
|   |    |   |
|   |    |   |
|_4_|    |_4_|
 s1        s2
class MinStack
{
private :
    stack < int > s1 ; //存数据
    stack < int > s2 ; //存各阶段最小数
public :
    
    void push ( int x )
    {
        s1 . push ( x );
        if ( s2 . empty () || x <= s2.top ()) 
           s2 . push ( x ); //如果s2为空,或者存入数小于等于之前最小数,则传入s2
    }
   
    void pop ()
    {
        if ( s1 . top () == s2 . top ()) 
           s2 . pop (); //如果pop的是当前极小值,则s2也跟着pop
        s1 . pop ();
    }
   
    int top ()
    {
        return s1 . top ();//返回data的栈顶即可
    }
   
    int getMin ()
    {
        return s2 . top (); //栈顶元素为当前最小数
    }
};

4.用栈实现队列

解题思路:用两个栈,插入 s1借助辅助栈s2将元素插入到栈底

举例:假如将序列[2,3]用栈存储来实现队列

入栈 2 ,此时s1,s2栈为空,将2入s1
|   |    |   |
|   |    |   |
|_2_|    |_ _|
 s1        s2

入栈3 ,此时s1不为空,出s1栈顶元素入s2中,再将3入栈s1,此时s2不为空,将s2栈顶元素入s1.输出序列[2,3]
|   |    |   |
|   |    |   |
|_ _|    |_2_|
 s1        s2

|   |    |   |
|   |    |   |
|_3_|    |_2_|
 s1        s2

|   |    |   |
| 2 |    |   |
|_3_|    |_ _|
 s1        s2
class MyQueue
{
   
private :
    stack < int > s1 ; //主栈
    stack < int > s2 ; //辅助栈
public :
    
    /** 插入元素 */
    void push ( int x )
    {
        while (! s1 . empty ())   //s1转移到s2
        {
            s2 . push ( s1 . top ());
            s1 . pop ();
        }
        s1 . push ( x ); //在s1中插入元素(处在栈底位置)
        while (! s2 . empty ())  //s2转移回s1
        {
            s1 . push ( s2 . top ());
            s2 . pop ();
        }
    }
   
    /** 删除并返回队列元素 */
    int pop ()
    {
        int top_element = s1 . top ();
        s1 . pop ();
        return top_element ;
    }
   
    /**获取栈顶元素 */
    int top ()
    {
        return s1 . top ();
    }
   
    /** 返回栈是否为空*/
    bool empty ()
    {
        return s1 . empty ();
    }
};

单调栈:
单调栈是比较特殊的栈结构,分为单调递增栈和单调递减栈,即从栈底元素到栈顶元素呈单调递增或单调递减,栈内序列满足单调性的栈;

单调栈用来解决下一个更大(更小)的元素相关问题.

5.下一个更大的元素
题目描述:给定两个 没有重复元素 的数组 s1,s2.其中s1 是 s2 的子集。找到 s1中每个元素在 s2中的下一个比其大的值。

s1 中数字 x 的下一个更大元素是指 x 在s2中对应位置的右边的第一个比 x 大的元素。如果不存在,对应位置输出 − 1。

解题思路:建立递减栈,对 s2中元素遍历,将元素依次放入递减栈,如果放入过程中,需要pop,则说明该元素是需要被pop出元素的下一个更大的数字,此时建立一个映射map,将该关系存入map中,遍历结束后,如果栈中还有元素,则将其pop出,且其对应的map值为-1,表示其后面没有比它更大的元素
对s1中的元素依次取map中对应的匹配即可.

class Solution {
public:
    vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) 
	{
		stack<int> min_stack;
		map<int,int> HASH;
		for(int i=0;i<nums2.size();i++)
		{
			while(!min_stack.empty()&&min_stack.top()<nums2[i])  //将小于num2[i]的元素pop出且建立映射 
			{
				HASH[min_stack.top()]=nums2[i];
				min_stack.pop();
			}
			min_stack.push(nums2[i]);
		}
		while(!min_stack.empty()) //对于栈中剩余元素建立映射
		{
			HASH[min_stack.top()]=-1;
			min_stack.pop();
		}
		vector<int> result;
		for(int i=0;i<nums1.size();i++)  //遍历取映射即可
			result.push_back(HASH[nums1[i]]);
		return result;
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值