301. Remove Invalid Parentheses 去除非法括号

32题的帖子里我们讨论了如果利用孤点找出最长有效括号
301这题要求我们除掉孤点。
去除孤点可以简单的把孤点去掉,肯定是一个正确解。
但是去孤点也可以通过把别的点去掉造成这个孤点的消失。
这里就没有什么好办法了。只能通过DFS加去重来做。

如果只找一个解,用孤点搞一搞。见下

    public String findOneSolution(String s) {
        boolean[] mustRemove = new boolean[s.length()];
        int lCnt = 0, rCnt = 0;
        for (int  i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (c == '(') lCnt++;
            if (c == ')') {
                if (lCnt > 0) lCnt--;
                else {
                    mustRemove[i] = true;
                    lCnt = 0;
                }
            }
        } 
        for (int i = s.length() - 1; i >= 0; i--) {
            char c = s.charAt(i);
            if (c == ')') rCnt++;
            if (c == '(') {
                if (rCnt > 0) rCnt--;
                else {
                    mustRemove[i] = true;
                    rCnt = 0;
                }
            }
        }
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < s.length(); i++) {
            if (!mustRemove[i]) sb.append(s.charAt(i));
        }
        return sb.toString();
        
    }

如果找所有解, 要用DFS加去重了。
我看到有人用BFS + 用SET去重。我个人很不喜欢那个解法。
我这个解法的时间复杂度, N^K, 因为每次从 N里面先一个, 最多选K次。
如果K比较小的时候。
但如果K 〜N的时候, 比如全都是((((. 这个其实没什么问题因为我去重了
但(a(a(a(a(a这种 就是O(2^(N/2))
我第三遍写这题的时候还是出bug了。
首先dfs的方式我选成了第一种就是取和不取的。这样不能去重
其次s.charAt(i)我写成了s.charAt(index)

class Solution {
    public List removeInvalidParentheses(String s) {
        int[] cnt = findBalances(s, true);
        List ans = new ArrayList<>();
        dfsHelper(s, cnt[0], cnt[1], "", 0, ans);
        return ans;
    }
    private void dfsHelper(String s, int left, int right, String cur, int index, List ans) {
        if (index == s.length() || (left + right == 0) ){
            if (isValid(cur + s.substring(index))) {
                ans.add(cur + s.substring(index));
            }
            return;
        }
        for (int i = index; i < s.length(); i++) {
            if (i != index && s.charAt(i) == s.charAt(i - 1)) continue;
            if (left > 0 && s.charAt(i) == '(') { 
          // 这里出了个bug, 应该是 s.charAt(i)的,我写成了s.charAt(index)
                dfsHelper(s, left - 1, right, cur + s.substring(index, i), i + 1, ans);
            } 
            if (right > 0 && s.charAt(i) == ')') {
                dfsHelper(s, left, right - 1, cur + s.substring(index, i), i + 1, ans);
            }
        }
    }
    private boolean isValid(String s) {
        int[] cnt = findBalances(s, false);
        return cnt[0] + cnt[1] == 0;
    }
    private int[] findBalances(String s, boolean findAll) {
        if (s == null || s.length() == 0) return new int[]{0, 0};
        int lCnt = 0, rCnt = 0;
        for (char c : s.toCharArray()) {
            if (c == '(') lCnt++;
            if (c == ')') {
                if (lCnt > 0) lCnt--;
                else {
                    rCnt++;
                    if (!findAll) return new int[]{1, 1};
                }
            }
        }
        return new int[]{lCnt, rCnt};
    }
}

你可能感兴趣的:(301. Remove Invalid Parentheses 去除非法括号)