代码随想录算法训练营第十一天 | Java |20. 有效的括号,1047. 删除字符串中的所有相邻重复项,150. 逆波兰表达式求值

20. 有效的括号

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

有效字符串需满足:

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

提示:

  • 1 <= s.length <= 104
  • s 仅由括号 '()[]{}' 组成

 思路:判断括号是否配对正确,用栈解决。遇到左半符号‘(’,‘{’,‘[’按照右半符号进栈,遇到右半符号直接与栈顶元素比较,如何一致,证明匹配。当遍历结束后栈不为空或者比较时不一致,证明配对错误。

注意:一旦出现匹配错误即可停止,不需要遍历完全。

Java实现

class Solution {
    public boolean isValid(String s) {
        Deque<Character> symbol = new LinkedList<>();
        int i=0;
        char sign;
        while(i < s.length()){
            sign = s.charAt(i++);
            switch (sign){
                case '(' :
                    symbol.push(')');
                    break;
                case '{' :
                    symbol.push('}');
                    break;
                case '[' :
                    symbol.push(']');
                    break;
                default:
                    if(symbol.isEmpty()||symbol.peek()!=sign)
                        return false;
                    symbol.pop();
            }
        }
        return symbol.isEmpty();
    }
}

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

题目: 给出由小写字母组成的字符串 S重复项删除操作会选择两个相邻且相同的字母,并删除它们。在 S 上反复执行重复项删除操作,直到无法继续删除。在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。

提示:

  1. 1 <= S.length <= 20000
  2. S 仅由小写英文字母组成。

思路:最复杂的是用循环,当出现重复时覆盖当前重复元素后,循环倒退回开头再次开始,时间复杂度最高。合理的选择递归或者栈,栈更适合一点。当前元素如果和栈顶元素一直,栈顶元素出栈,向后遍历比较,最终留在栈中的为不重复的剩余元素。

注意:如果使用循环,请注意每次删除重复元素后要从头开始循环。

Java实现

class Solution {
    public String removeDuplicates(String s) {
        StringBuffer res = new StringBuffer();
        int top=-1;
        for(int i=0;i<s.length();i++){
            char c = s.charAt(i);
            if(top>=0 && res.charAt(top)==c){
                res.deleteCharAt(top);
                top--;
            }
            else{
                res.append(c);
                top++;
            }
        }
        return res.toString();
        
        // 用循环实现
        // char[] ch = s.toCharArray();
        // int i=0;
        // int l= ch.length;
        // while(i<l-1){
        //     if(ch[i]==ch[i+1]){
        //         for(int j=i;j<l-2;j++){
        //             ch[j]=ch[j+2];
        //         }
        //         l=l-2;
        //         i=0;
        //     }
        //     else{
        //         i++;
        //     } 
        // }
        // char[] ss = new char[l];
        // i=0;
        // while(i<l){
        //     ss[i] = ch[i];
        //     i++;
        // }
        // return new String(ss);
    }
}

 3 150. 逆波兰表达式求值

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

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

注意:

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

提示:

  • 1 <= tokens.length <= 104
  • tokens[i] 是一个算符("+""-""*" 或 "/"),或是在范围 [-200, 200] 内的一个整数

 思路:实质为实现后缀表达式,用栈实现。当遇到数字入栈,遇到符号将前两个数字出栈组合符号进行计算,将得到的结果入栈,继续遍历。

注意:除法运算应注意区分除数和被除数。

Java实现

class Solution {
    public int evalRPN(String[] tokens) {
        Deque<Integer> stack = new LinkedList();
        for(String s:tokens){
            if("+".equals(s)){
                stack.push(stack.pop()+stack.pop());
            } else if("-".equals(s)){
                stack.push(-stack.pop()+stack.pop());
            } else if("*".equals(s)){
                stack.push(stack.pop()*stack.pop());
            } else if("/".equals(s)){
                int temp1 = stack.pop();
                int temp2 = stack.pop();
                stack.push(temp2/temp1);
            } else{
                stack.push(Integer.valueOf(s));
            }
        }
    return stack.pop();
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值