Java栈题目练习

删除字符串中的所有相邻重复项目

题目解析 :就是不断删除字符串中相邻重复项,删除后可能又有新的要删除
解法:使用栈的思想,每次放入元素都要判断与前一个已经存入字符串末尾进行比较,如果相同就删除这个字符串,如果不相同或者没有字符就放入

java 复制代码
class Solution {
    public String removeDuplicates(String s) {
        //可以使用数组模拟栈
        //如果与最后元素相同就进入,反之就删除
        StringBuffer ret = new StringBuffer();

        for(char ch : s.toCharArray()){
            if(ret.length() == 0 || ret.charAt(ret.length() - 1) != ch){
                ret.append(ch);
            }else{
                ret.deleteCharAt(ret.length()-1);
            }
        }
        return ret.toString();
    }
}

比较含退格的字符串

题目解析 :给你两个字符串,就是遇到'#'就会删除前一个字符,通过这个操作后判断两个字符串是否相等即可
解法:和上题目思路一样,使用数组来模拟栈

java 复制代码
class Solution {
    public boolean backspaceCompare(String s, String t) {
        return changeStr(s).equals(changeStr(t));
    }
    public String changeStr(String s){
        StringBuffer ret = new StringBuffer();
        for(char ch : s.toCharArray()){
            if(ch != '#'){
                ret.append(ch);
            }else{
                //进行出栈
                if(ret.length() != 0){
                    ret.deleteCharAt(ret.length()-1);
                }
            }
        }
        return ret.toString();
    }
}

基本计算器||

题目解析 :给了一个字符串里面有运算符和数字字符,让我们求出里面结果

思路:直接使用栈和一个op变量即可,op存放数字前一个运算符

遍历字符串即可

如果是运算符 ,op 修改即可

反之如果是数num

op = '+' 直接入栈

op = '-' 入栈其相反数

op = '*' 将stack.pop() * num入栈

op = '/'将stack.pop() / num入栈

如果当前字符是空格,直接跳过即可


java 复制代码
class Solution {
    public int calculate(String s) {
        char op = '+';  //使用这个表示其字符前面的运算符
        Stack<Integer> stack = new Stack<>();
        int n = s.length();
        char ch[] = s.toCharArray();
        int i = 0;
       while(i < n){
            //处理空格
            if(ch[i] == ' '){
                i++;
            }else if(ch[i] >= '0' && ch[i] <= '9'){
                //如果是一个数
                //提取出来这个数,这个数不一定是个位数
                int tem = 0;
                while(i < n && (ch[i] >= '0' && ch[i] <= '9')){
                    tem = tem*10 + (ch[i] - '0');
                    i++;
                }
                //处理这个数
                if(op == '+'){
                    stack.push(tem);
                }else if(op == '-'){
                    stack.push(-tem);
                }else if(op == '*'){
                    //将与栈顶元素运算之后入栈
                    stack.push(stack.pop() * tem);
                }else {
                    stack.push(stack.pop() / tem);
                }
            }else{
                //更新运算符
                op = ch[i];
                i++;
            }
        }
        int ret = 0;
        //最后直接让栈中所有元素进行相加即可
        while(!stack.isEmpty()){
            ret += stack.pop();
        }
        return ret;
    }
}

字符串解码

题目解析 :将这个字符串解析出来,数字表示后面[]内需要重复的次数,并且里面[ ] 里面可能嵌套[ ] ,如果嵌套就要先把里面解析出来才可以解析外面
思想 :这里需要记录这段字符重复次数n,和这段字符,并且还要判断何时进行重复操作,因此这里就需要两个栈进行操作,一个栈用来方重复次数
另一个放字符串

分为四种情况

1.遇到数

2.遇到'['

3.遇到']'

4.遇到正常字符



java 复制代码
class Solution {
    public String decodeString(String s) {
        //直接使用两个栈进行分类讨论即可
        Stack<StringBuffer> Strstack = new Stack<>();//字符栈
        Stack<Integer> Numstack = new Stack<>();//数字栈

        Strstack.push(new StringBuffer(""));//先给栈放入一个空的字符串为了后面拼接

        int n  = s.length();
        int i = 0;
        char[] ch = s.toCharArray();
        while(i < n){
            //1.如果是数字字符
            if(ch[i] >= '0' && ch[i] <= '9'){
                int tem = 0;
                while(i < n &&(ch[i] >= '0' && ch[i] <= '9')){
                    tem = tem * 10 + (ch[i] - '0');
                    i++;
                }
                //放入数字栈中
                Numstack.push(tem);
            }else if(ch[i] == '['){
                //将后面的字符全部提取出来
                i++;
                StringBuffer ret = new StringBuffer();
                while(i < n &&(ch[i] >= 'a' && ch[i] <= 'z')){
                    ret.append(ch[i]);
                    i++;
                }
                Strstack.push(ret);
                
            }else if(ch[i] == ']'){
               
                //解析出来,将这个拼接到栈顶元素后面
                int num = (int)Numstack.pop();
                StringBuffer str = Strstack.pop();

                while(num > 0){
                    //直接拼接到栈顶元素后面
                    Strstack.peek().append(str);
                    num--;
                }
                 i++;
            }else{
                //遇到单独字符串,直接提取出来拼接到栈顶元素后面即可
                StringBuffer ret = new StringBuffer();
                while(i < n &&(ch[i] >= 'a' && ch[i] <= 'z')){
                    ret.append(ch[i]);
                    i++;
                }
                Strstack.peek().append(ret);
               
            }
        }
        return Strstack.pop().toString();

    }
}

验证栈序列

题目解析 :因为栈是先入后出,因此这里给出一个入栈顺序,让我们判断这个出栈顺序是否符合栈先入后出要求
思路 :直接使用一个栈用来存放入栈元素,入栈以后就要判断其栈顶元素是否与出栈元素一样,如果一样就进行出栈,判断下一个元素,此时的出栈可能是连续出了多次栈,因此这里出栈要采用循环

就这样不断入栈出栈,如果最后栈为空,或者出栈数组遍历完,其就说明出栈顺序是对的

java 复制代码
class Solution {
    public boolean validateStackSequences(int[] pushed, int[] popped) {
        //直接在进栈之后进行判断栈顶元素与要出的元素是否相同即可
        Stack<Integer> stack = new Stack<>();
        int i = 0;
        int n = popped.length;
        for(int x : pushed){
            //入栈
            stack.push(x);
            //判断是否要出栈,此时可能回连续出栈,所以这里是一个循环
            while(!stack.isEmpty()&&stack.peek() == popped[i]){
              stack.pop();
              i++;
            }
        }
        //最后栈为空或者popped遍历完才是正确的出栈序列
        if(i == n||stack.isEmpty() ){
            return true;
        }
        return false;
    }
}
相关推荐
xxp43211 小时前
Qt 多线程
开发语言·qt
864记忆1 小时前
在IDEA中如何使用翻译插件?
java·ide·intellij-idea
w***48821 小时前
Springboot 3项目整合Knife4j接口文档(接口分组详细教程)
java·spring boot·后端
k***45991 小时前
SpringBoot【实用篇】- 测试
java·spring boot·后端
FeiHuo565151 小时前
微信个人号API二次开发:如何提高开发效率和质量
java·开发语言·python·php
vortex51 小时前
什么是Unix哲学?或者:如何像克尼汉一样思考、像里奇一样编码、像汤普森一样架构
java·架构·unix
q***54751 小时前
java进阶--多线程学习
java·开发语言·学习
hellotutu1 小时前
vue2+springboot通过 FormData 手动封装图片数据上传
java·vue.js·spring boot·后端·ui
某空m1 小时前
【Android】组件化搭建
android·java·前端