【LeetCode题型总结-01】如何得到有效的括号字符串?

来源:LeetCode hot 100

20.有效的括号

301.删除无效的括号

[1] 20.有效的括号(easy)

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

有效字符串需满足:

左括号必须用相同类型的右括号闭合。 左括号必须以正确的顺序闭合。

1、JAVA题解(构建括号键值对+括号压栈判断栈空)
class Solution {
    
    
    public boolean isValid(String s) {
    
    
        int n = s.length();
        if (n % 2 == 1) {
    
    
            return false;
        }
        Map<Character, Character> pairs = new HashMap<Character, Character>() {
    
    {
    
    
            put(')', '(');
            put(']', '[');
            put('}', '{');
        }};
        Deque<Character> stack = new LinkedList<Character>();
        for (int i = 0; i < n; i++) {
    
    
            char ch = s.charAt(i);
            if (pairs.containsKey(ch)) {
    
    
                if (stack.isEmpty() || stack.peek() != pairs.get(ch)) {
    
    
                    return false;
                }
                stack.pop();
            } else {
    
    
                stack.push(ch);
            }
        }
        return stack.isEmpty();
    }
}
2、C++题解(利用括号ASCII值差+括号压栈判断栈空)
class Solution {
    
    
public:
    bool isValid(string s) {
    
    
        vector<char>  stack;
        int n = s.size();

        for(int i = 0 ; i < n ; i++ ){
    
    
            if(stack.empty() == true){
    
    
                stack.push_back(s[i]);
            }else if(s[i] - stack.back() == 1 ||s[i] - stack.back() == 2){
    
    
                stack.pop_back();
            }else{
    
    
                stack.push_back(s[i]);
            }
        }
        return stack.empty();
    }
};

[2] 301.删除无效的括号(hard)

给你一个由若干括号和字母组成的字符串 s ,删除最小数量的无效括号,使得输入的字符串有效。

返回所有可能的结果。答案可以按 任意顺序 返回。

JAVA题解
class Solution {
    
    
    List<String> res = new ArrayList<>();
    public List<String> removeInvalidParentheses(String s) {
    
    
        //计算出要移除的左右括号数
        int lr = 0, rr = 0;
        for(int i = 0; i < s.length(); ++i){
    
    
            if(s.charAt(i) == '(') lr++;
            if(s.charAt(i) == ')'){
    
    
                if(lr > 0){
    
    
                    lr--;
                }else{
    
    
                    rr++;
                }
            }
        }
        //进行回溯
        backTrack(0, lr, rr, s);
        return res;
    }

    //回溯,移除括号
    void backTrack(int start, int lr, int rr, String s){
    
    
        //完成条件:
        //要移除的左右括号数都为零 且 s串有效,则添加至答案数组
        if(lr == 0 && rr == 0){
    
    
            if(isValid(s)) res.add(s);
        }
        //for s
        //离开条件
        //做出选择
        //回溯
        //撤销选择
        for(int i = start; i < s.length(); ++i){
    
    
            //遇到两个连续的相同括号,跳过第二个括号的处理
            if(i > start && s.charAt(i) == s.charAt(i-1)) continue;
            //若为左括号且要移除的左括号数大于零,则进行回溯
            //s.substring(0, i) + s.substring(i + 1):表示从s中移除第i个字符后形成的新串
            if(s.charAt(i) == '(' && lr > 0){
    
    
                backTrack(i, lr - 1, rr, s.substring(0, i) + s.substring(i + 1));
            }
            if(s.charAt(i) == ')' && rr > 0){
    
    
                backTrack(i, lr, rr - 1, s.substring(0, i) + s.substring(i + 1));
            }
        }
    };

    //判定是否有效
    boolean isValid(String s){
    
    
        Stack<Character> stack = new Stack<>();
        for(int i = 0; i < s.length(); ++i){
    
    
            //若该字符为右括号且栈顶为左括号,则栈顶元素出栈,跳过
            if(!stack.isEmpty() && s.charAt(i)==')' && stack.peek()=='('){
    
    
                stack.pop();
                continue;
            }
            //若该字符为非括号,则跳过
            if(s.charAt(i)!='(' && s.charAt(i)!=')') continue;
            stack.push(s.charAt(i));
        }
        //返回栈的判空,若为空栈则说明有效
        return stack.isEmpty();
    }
}
思路整理:
1.首先遍历字符串,计算出要移除的左括号数和右括号数。(不要纠结左右括号的排列顺序,只专注于要移除的数量!作为后面回溯的资本!)

2.接着进行回溯操作,回溯完成的判断条件为【要移除的左右括号数都为零】且【s串有效】,满足则添加至答案数组。

3.返回答案。
技巧总结:
1.回溯函数尽量定义为 无返回值类型(void);

2.移除字符串中某个位置的字符可以用s.substring(0, i) + s.substring(i + 1)(表示从s中移除第i个字符后形成的新串)

3.遇到两个连续的相同括号,为了避免重复的答案,必须跳过第二个括号的处理。

4.回溯函数形参列表该怎么写,注意start参数。

猜你喜欢

转载自blog.csdn.net/weixin_43363720/article/details/121423129
今日推荐