2. <tag-栈和常规题>-lt.20. 有效的括号 + lt.1047. 删除字符串中的所有相邻重复项
lt.20. 有效的括号
[案例需求]

[思路分析一, 栈的使用]
用栈存储左括号, 然后当遇到右括号时, 当栈不为空时, 出栈一个元素, 如果不是互相搭配的左右括号时, 立刻返回true;
如果遇到右括号, 而栈此时已经是空栈了, 那肯定要返回 false;
最终整个符号的char数组遍历完毕, 只需要要返回对栈是否为空的判断结果即可;
[代码实现]
class Solution {
    public boolean isValid(String s) {
        //左括号入栈, 遇到右括号出栈
        char[] chars = s.toCharArray();
        Stack<Character> st = new Stack<>();
        for(char ch : chars){
            //左括号
            if(ch == '(' || ch == '[' || ch == '{'){
                st.push(ch);
            }else{
                if(!st.isEmpty()){
                    if(ch == ')'){
                        if(st.pop() != '(')return false;
                    }else if(ch == ']'){
                        if(st.pop() != '[')return false;
                    }else{
                        if(st.pop() != '{')return false;
                    }
                }else{
                    return false;
                }
            }
        }
        return st.isEmpty();
    }
}
[思路分析二, 栈和哈希表的使用]
[代码示例]
class Solution {
    public boolean isValid(String s) {
        //首先,判断s长度若为奇数,则一定不成对,返回false
        int n = s.length();
        if(n%2 == 1)
            return false;
        //定义一个辅助栈,判断')'在s中是否有对应的'('
        Map<Character,Character> pairs = new HashMap<Character,Character>(){{
            put(')','(');
            put(']','[');
            put('}','{');
        }};
        //定义栈
        Deque<Character> stack = new LinkedList<Character>();
        for(int i=0;i<s.length();i++){
           //获取s的第i个字符
           char ch =s.charAt(i);
           //判断ch是否为右括号
           if(pairs.containsKey(ch)){
               //判断栈是否为空或者栈顶元素是否等于ch的value,若满足其中一个则返回false
               //若栈为空则表示,右括号在做左括号前面;若栈顶元素和ch的value不相等,则不匹配
               if(stack.isEmpty() || stack.peek()!=pairs.get(ch)){
                   return false;
               }
               stack.pop();
           }else{
              stack.push(ch);
           }
        }
        return stack.isEmpty();
    }
}
lt.1047. 删除字符串中的所有相邻重复项
[案例需求]

[思路分析一, 学弱解法(栈存储, 再转化为String)]
充分理解题意后,我们可以发现,当字符串中同时有多组相邻重复项时,我们无论是先删除哪一个,都不会影响最终的结果。因此我们可以从左向右顺次处理该字符串。
而消除一对相邻重复项可能会导致新的相邻重复项出现,如从字符串 abba 中删除 bb会导致出现新的相邻重复项 aa出现。因此我们需要保存当前还未被删除的字符。
- 一种显而易见的数据结构呼之欲出:栈。我们只需要遍历该字符串,如果当前字符和栈顶字符相同,我们就贪心地将其消去,否则就将其入栈即可。
代码
在C++代码中,由于std::string类本身就提供了类似「入栈」和「出栈」的接口,因此我们直接将需要被返回的字符串作为栈即可。对于其他的语言,如果字符串类没有提供相应的接口,则需要在遍历完成字符串后,使用栈中的字符显式地构造出需要被返回的字符串。
[代码实现]
class Solution {
    public String removeDuplicates(String s) {
        char[] chars = s.toCharArray();
        Stack<Character> st = new Stack<>();
        st.push(chars[0]);
        
        for(int i = 1; i < chars.length; i++){
            if(!st.isEmpty() && st.peek() == chars[i]){
                st.pop();
                continue;
            }else{
                st.push(chars[i]);
            }
        }
        //stack -> string ?
        // StringBuilder sb = new StringBuilder();
        // while(!st.isEmpty()){
        //     sb.append(st.pop());
        // }
        
        char[] res = new char[st.size()];
        int index = st.size() - 1;
        while(!st.isEmpty()){
            res[index--] = st.pop();
        }
        return String.valueOf(res);
    }
}
[思路分析二, 用StringBuilder作为栈]
[代码实现]
class Solution {
    public String removeDuplicates(String s) {
        StringBuilder stack = new StringBuilder();
        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();
    }
}
[思路分析三, 用数组作为栈]
[代码实现]
//1.  用数组作为栈
class Solution {
    public String removeDuplicates(String S) {
        char[] s = S.toCharArray();
        int top = -1;
        for (int i = 0; i < S.length(); i++) {
            if (top == -1 || s[top] != s[i]) {
                s[++top] = s[i];
            } else {
                top--;
            }
        }
        return String.valueOf(s, 0, top + 1);
    }
}

 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号