删除无效的括号

题目:
给你一个由若干括号和字母组成的字符串 s ,删除最小数量的无效括号,使得输入的字符串有效。
返回所有可能的结果。答案可以按 任意顺序 返回。

示例 1:
输入:s = “()())()”
输出:["(())()","()()()"]

示例 2:
输入:s = “(a)())()”
输出:["(a())()","(a)()()"]

示例 3:
输入:s = “)(”
输出:[""]

解题思路: 首先计算出字符串中多余的左右括号数, 再用dfs来枚举出删除相应数目的左右括号(优先删除右括号, 防止首字符是右括号导致所有结果都无效)后的字符串是否是有效字符串

class Solution {

    private List<String> ans = new ArrayList();

    public List<String> removeInvalidParentheses(String s) {
        char[] ch = s.toCharArray();
        int l = 0, r = 0;
		// 计算多余的左右括号 
        for(char c : ch) {
            if(c == '(') {
                l++;
            } else if(c == ')') {
                if(l > 0) {
                    l--;
                } else {
                    r++;
                }
            }
        }

        dfs(s, l, r, 0);
        return ans;
    }

    private boolean isValid(String s) {
        char[] ch = s.toCharArray();
        int count = 0;
        for(char c : ch) {
            if(c == '(') {
                count++;
            } else if(c == ')') {
                count--;
            }

            if(count < 0) {
                return false;
            }
        }

        return count == 0;
    }

    private void dfs(String s, int l, int r, int cur) {
        if(l == 0 && r == 0) {
            if(isValid(s)) {
                ans.add(s);
            }
            return ;
        }

        for(int i = cur; i < s.length(); i++) {
        	// 相邻字符相同删除最后一个即可 防止答案重复
            if(i != cur && s.charAt(i) == s.charAt(i - 1)) {
                continue ;
            }

            char c = s.charAt(i);
            StringBuffer sb = new StringBuffer(s);
            if(c == ')' && r > 0) {
                dfs(sb.deleteCharAt(i).toString(), l, r - 1, i);
            } else if(c == '(' && l > 0) {
                dfs(sb.deleteCharAt(i).toString(), l - 1, r, i);
            }
        }
    }
}