代码随想录Day11-栈与队列02 20. 有效的括号 1047. 删除字符串中的所有相邻重复项 150. 逆波兰表达式求值

20. 有效的括号

        括号匹配题,肯定是要用栈啦。因为给的是一个字符串,所以要先把字符串转成一个一个的字符,每个字符就是一个括号。遍历这个字符数组,如果遇到了一个左括号,就把他放到栈中,如果遇到了一个右括号,就把这个右括号跟栈顶的左括号对比一下,匹配上了就把左括号从栈里拿出来,匹配不上就直接返回false。因为括号匹配的原则就是就近嘛~

        但是这么写有个小坑,就是要判断栈里没有元素,但是来了个右括号的情况。如果不判断,直接在第二个if语句中让栈给出他的栈顶元素就会报错。

        最后返回st.isEmpty()的原因是可能遍历完数组但还是有部分左括号没有匹配到,这时候就属于匹配失败,栈也不为空,返回false。

class Solution {
    public boolean isValid(String s) {
        char[] c = s.toCharArray();
        Stack<Character> st = new Stack<>();
        //遍历字符串中的每一个字符
        for(char c1 : c){
            //栈中没有元素,但遇到右括号的情况,返回false
            if(st.isEmpty()&&(c1==')'||c1==']'||c1=='}')){
                return false;
            }
            //遇到左括号,就放到栈里
            if(c1=='('||c1=='['||c1=='{'){
                st.push(c1);
            //遇到右括号,如果跟栈顶元素匹配就弹出栈顶元素
            }else if((c1==')'&&st.peek()=='(')||(c1==']'&&st.peek()=='[')||(c1=='}'&&st.peek()=='{')){
                st.pop();
            }else{
                return false;//匹配失败,返回false
            }
        }
        return st.isEmpty();//如果最后栈不是空的,说明还有括号没匹配上,也是false
    }
}

        看到题解用了Map欸~又没想到qwq

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

        原理跟括号匹配好像差不多?但是这也太慢啦。。

        执行用时:80 ms, 在所有 Java 提交中击败了48.16%的用户。。。

class Solution {
    public String removeDuplicates(String s) {
        char[] c = s.toCharArray();
        Stack<Character> st = new Stack<>();
        for(char c1: c){
            //栈非空且匹配,弹出栈顶元素
            if(!st.isEmpty() && c1 == st.peek()){
                st.pop();
            }else{
                //否则往栈里添加元素
                st.push(c1);
            }
        }
        //把栈里元素拼起来
        StringBuilder sb = new StringBuilder();
        while(!st.isEmpty()){
            sb.append(st.pop());
        }
        return sb.reverse().toString();
    }
}

        把题解👇copy过来慢慢看,用到了栈的思想,但是没有真的定义一个栈欸,只是移动top的位置让top指针始终指向栈顶。妙蛙

class Solution {
    public String removeDuplicates(String s) {
        StringBuffer stack = new StringBuffer();
        int top = -1;
        for (int i = 0; i < s.length(); ++i) {
            char ch = s.charAt(i);
            if (top >= 0 && stack.charAt(top) == ch) {
                stack.deleteCharAt(top);
                --top;
            } else {
                stack.append(ch);
                ++top;
            }
        }
        return stack.toString();
    }
}

150. 逆波兰表达式求值

        (●'◡'●)就按照题目要求说的一步一步写就是下面这样啦,虽然有很多if else但是很容易看懂!

        就是时间有点长:执行用时:6 ms, 在所有 Java 提交中击败了53.56%的用户

        有一个很小很小的需要注意的地方就是,减和除的时候两个数的位置别弄反了呀~

class Solution {
    public int evalRPN(String[] tokens) {
        Stack<Integer> st = new Stack<>();
        for(String token: tokens){
            //遇到数字字符串,把它转成int类型
            if(!token.equals("+") && !token.equals("-") && !token.equals("*") && !token.equals("/")){
                st.push(Integer.parseInt(token));
            //遇到+,就相加,后面同理
            }else if(token.equals("+")){
                st.push(st.pop()+st.pop());
            }else if(token.equals("-")){
                int p1 = st.pop();
                int p2 = st.pop();
                st.push(p2-p1);
            }else if(token.equals("*")){
                st.push(st.pop()*st.pop());
            }else if(token.equals("/")){
                int p1 = st.pop();
                int p2 = st.pop();
                st.push(p2/p1);
            }
        }
        return st.pop();
    }
}

        else if可以换成switch的嘞!

        这段代码是David大佬写的感觉比我的这个好看点(●ˇ∀ˇ●)

public int evalRPN(String[] tokens) {
        Stack<Integer> stack = new Stack<>();
        for (String item : tokens) {
            if ("+".equals(item) || "-".equals(item) || "*".equals(item) || "/".equals(item)) {
                int p1 = stack.pop();
                int p2 = stack.pop();
                if ("+".equals(item)) stack.push(p2+p1);
                else if ("-".equals(item)) stack.push(p2-p1);
                else if ("*".equals(item)) stack.push(p2*p1);
                else if ("/".equals(item)) stack.push(p2/p1);
            } else {
                stack.push(Integer.valueOf(item));
            }
        }
        return stack.peek();
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值