代码随想录刷题Day14

64 阅读2分钟
  1. 20. 有效的括号
  • 我自己想的有点复杂
    public boolean isValid(String s) {
        Stack<Character> ck=new Stack<>();
        int len=s.length();
        if(len%2!=0) return false;
        for(int i=0;i<s.length();i++){
            char ch=s.charAt(i);
            if(ch=='('||ch=='{'||ch=='[')//遇到左括号就入栈
                ck.push(ch);
            else if(ch==')'||ch=='}'||ch==']'){
                if(ck.isEmpty()){//遇到右括号先判断栈是否为空,为空则说明没有左括号相匹配直接false
                    return false;
                }
                char top=ck.peek();
                if((ch==')'&& top=='(')||(ch=='}'&& top=='{')||(ch==']'&& top=='[')){//判断栈顶是否为与当前右括号相匹配的左括号,是则左括号出栈
                    ck.pop();
                }else return false;//不是的话直接false
            }  
        }
        return ck.isEmpty();//匹配成功则最终栈为空
    }
}
  • 代码随想录解法

先来分析一下 这里有三种不匹配的情况,

  1. 字符串里左方向的括号多余了 ,所以不匹配。 看图 image.png

这种情况已经遍历完了字符串,但是栈不为空,说明有相应的左括号没有右括号来匹配,所以return false

  1. 括号没有多余,但是 括号的类型没有匹配上。 看图 image.png

遍历字符串匹配的过程中,发现栈里没有要匹配的字符。所以return false

  1. 字符串里右方向的括号多余了,所以不匹配。 看图 image.png

遍历字符串匹配的过程中,栈已经为空了,没有匹配的字符了,说明右括号没有找到对应的左括号return false

字符串遍历完之后,栈是空的,就说明全都匹配了。

但还有一些技巧,在匹配左括号的时候,右括号先入栈,就只需要比较当前元素和栈顶相不相等就可以了,比左括号先入栈代码实现要简单的多了!

class Solution {
    public boolean isValid(String s) {
        Stack<Character> ck=new Stack<>();
        for(int i=0;i<s.length();i++){
            char ch=s.charAt(i);
            if(ch=='('){
                ck.push(')');
            }else if(ch=='{'){
                ck.push('}');
            }else if(ch=='['){
                ck.push(']');
            }else if(ck.isEmpty() || ck.peek()!=ch){//栈已经为空了,没有匹配的字符了,说明右括号没有找到对应的左括号return false;如果是右括号判断是否和栈顶元素匹配,不匹配返回false
                return false;
            }else{//如果匹配则pop
                ck.pop();
            }   
        }
        return ck.isEmpty();
    }
}
  1. 1047. 删除字符串中的所有相邻重复项
  • 栈(自己想的)
    public String removeDuplicates(String s) {
        Stack<Character> ck=new Stack<>();
        int len=s.length();
        for(int i=0;i<s.length();i++){//遍历该字符串,如果当前字符和栈顶字符相同,我们就贪心地将其消去,否则就将其入栈即可
            char ch=s.charAt(i);
            if(!ck.isEmpty() && ch==ck.peek()){
                ck.pop();
            }else{
                ck.push(ch);
            }  
        }
        StringBuilder ans = new StringBuilder();
        while (!ck.isEmpty()) {
            ans.append(ck.pop());
        }
        return ans.reverse().toString();
    }
}
  • 官解也是用了栈的思想,只不过直接在String上操作
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();
    }
}