栈相关题目

1.括号匹配问题.

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

有效字符串需满足:

左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
每个右括号都有一个对应的相同类型的左括号。

具体代码如下:


package demo6;

import java.util.Stack;
/*1逆序打印链表

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

        有效字符串需满足:

        左括号必须用相同类型的右括号闭合。
        左括号必须以正确的顺序闭合。
        每个右括号都有一个对应的相同类型的左括号。




 */
//下面完成括号匹配的代码
public class Solution{
    //如果匹配返回true,否则返回false
    //基本思路是,如果遇见左括号,就存进栈,如果遇见右括号就出战进行比较,直到栈空
    public boolean isValid(String S){
        //首先创建一个栈用来存储左括号.
        Stack<Character> stack=new Stack<>();
        //接下来要循环遍历这个字符串,直到字符串走完
        for(int i=0;i<S.length();i++){
            //这里是
            //如果是左括号就需要金星入栈操作,左括号有三种
            //先将这个括号置为字符
            char ch=S.charAt(i);//charAt()方法是一个能够用来检索特定索引下的字符的String实例方法.
            // 返回指定索引位置的
            //char值,索引范围为0到length()-1;
            if(ch=='('||ch=='{'||ch=='['){
                stack.push(ch);
            }
            //这里就是右括号呗
            else{
                //判断是否能匹配前,首先要判断是否空.
                if(stack.isEmpty()){
                    return false;
                }
                //如果不是空才进行比较.
                char ch2=stack.peek();
                //如果两个相等就要进行出栈
                if(ch==')'&&ch2=='('||ch==']'&&ch2=='['||ch=='}'&&ch2=='{'){
                    //比较相同了,就要进行出战操作.
                    stack.pop();
                }
            }
            //循环结束之后,如果栈中还有括号,那么就返回false;反之就返回true
        }
        if(stack.isEmpty()){
            return true;
        }
        return false;
    }
    //在这里进行测试
    public static void main(String[] args){
         Solution  t1=new Solution();
         String s1="[]{}";
        System.out.println(t1.isValid(s1));
    }
}


2.逆波兰表达式求值

给你一个字符串数组 tokens ,表示一个根据 逆波兰表示法 表示的算术表达式。

请你计算该表达式。返回一个表示表达式值的整数。

注意:

有效的算符为 '+'、'-'、'*' 和 '/' 。
每个操作数(运算对象)都可以是一个整数或者另一个表达式。
两个整数之间的除法总是 向零截断 。
表达式中不含除零运算。
输入是一个根据逆波兰表示法表示的算术表达式。
答案及所有中间计算结果可以用 32 位 整数表示。这个问题可以根据栈来求解具体代码如下:
 

package demo6;

import java.util.Stack;

public class Demo1 {
    //逆波兰表达式求值
    public int evalRPN(String[] tokens){
        //首先创建一个整形的栈用来存储数据
        Stack<Integer> s1=new Stack<>();
        //还是要遍历这个字符串
        for(int i=0;i<tokens.length;i++){
            //首先要判断是数字还是运算符号
            //字符串.equals()可以比较两个字符串是否相等
            if(tokens[i].equals("+")||tokens[i].equals("-")||tokens[i].equals("*")||tokens[i].equals("/")){
                //如果是字符串就要进行,运算.
                int t2=s1.pop();
                int t1=s1.pop();
                //接下俩要进行运算
                if(tokens[i].equals("+")){
                    s1.push(t1+t2);
                }
                if(tokens[i].equals("-")){
                    s1.push(t1-t2);
                }
                if(tokens[i].equals("*")){
                    s1.push(t1*t2);
                }
                if(tokens[i].equals("/")){
                    s1.push(t1/t2);
                }
            }else{
                //这里就是数字了,怎么把这个字符串转成数字呢?
                //可以使用Integer.valueof()这个方法来进行修改
                //进行修改
                int t3=Integer.valueOf(tokens[i]);
                //那么如果是数字,把数字入栈即可
                s1.push(t3);
            }
        }//for循环完成后,这个字符串就遍历完了.将栈中的那个数字出栈即可
        return s1.pop();
    }
    public static void main(String[] args){
        //在这里进行测试
        String[] tokens= {"2","1","+","10","*"};
        Demo1 t1=new Demo1();
        System.out.println(t1.evalRPN(tokens));
    }
}
/*
输入:tokens = ["2","1","+","10","*"]
输出:9
解释:该算式转化为常见的中缀算术表达式为:((2 + 1) * 10) = 30
 */

3. 出栈入栈匹配问题

描述
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。
1. 0<=pushV.length == popV.length <=1000
2. -1000<=pushV[i]<=1000
3. pushV 的所有数字均不相同

package demo6;
import java.util.Stack;
public class Demo2 {
    /*
    描述
     输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。
     假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,
     序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。
     */
    public boolean IsPopOrder(int[] t1,int[] t2){
        //首先用一个栈来记录t1
        Stack<Integer> t3=new Stack<>();
        //首先是要遍历完t1这个数组
        int j=0;
        for(int i=0;i<t1.length;i++){
            //每一次循环都要进行入栈一次
            t3.push(t1[i]);
            //接下来要进行的是t2中的元素和t1中的元素进行比较
            //如果相同一个进行出栈,一个进行后移
            while(!t3.empty()&& j<t2.length&&t3.peek()==t2[j]){
                t3.pop();
                j++;
            }
        }
        return j==t2.length;
    }
    public static void main(String[] args){
        int[] t1={1,2,3,4,5};
        int[] t2={5,4,3,2,1};
        Demo2 t3=new Demo2();
        System.out.println(t3.IsPopOrder(t1,t2));
    }
}

 4.最小栈问题

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

实现 MinStack 类:

  • MinStack() 初始化堆栈对象。
  • void push(int val) 将元素val推入堆栈。
  • void pop() 删除堆栈顶部的元素。
  • int top() 获取堆栈顶部的元素。
  • int getMin() 获取堆栈中的最小元素.

普通的栈由于出栈的顺序是有要求的,所以无法在常数时间内获取到堆栈中的最小元素.所以需要格外创建一个栈用来存储栈中较小的元素,便于在常数时间内检索到最小元素.具体代码如下:

package demo6;

import java.util.Stack;

public class Minstack {
    //首先创建两个栈用来存储
    private Stack<Integer> t1;
    private Stack<Integer> t2;
    //接下来是构造方法
    public Minstack(){
        this.t1=new Stack<>();
        this.t2=new Stack<>();
    }
    //push方法,
    public void push(int val) {
         //在入栈的时候,由于要在常数时间内找到最小的,所以要把最小的放在另一个栈
        t1.push(val);
        //判断是否需要进入另一个栈
        if(t2.empty()){
            t2.push(val);
        } else{
            if(val<=t2.peek()){
                t2.push(val);
            }
        }
    }
    public void pop() {
         //出栈,删除的时候要进行比较
        if(t1.peek()==t2.peek()){
            t1.pop();
            t2.pop();
        }
        else{
            t1.pop();
        }
    }
    public int top() {
         return t1.peek();
    }
    public int getMin() {
         return t2.peek();
    }
}


 

  • 8
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值