LeetCode 301. Remove Invalid Parentheses(搜索)

301. Remove Invalid Parentheses

Hard

Remove the minimum number of invalid parentheses in order to make the input string valid. Return all possible results.

Note: The input string may contain letters other than the parentheses ( and ).

Example 1:

Input: “()())()”
Output: ["()()()", “(())()”]
Example 2:

Input: “(a)())()”
Output: ["(a)()()", “(a())()”]
Example 3:

Input: “)(”
Output: [""]

题意

给定一个含有左右括号的字符串(可能还包含其他字符),要求删去最少的左右括号使之合法,输出所有可能的合法字符串

思路

搜索 + 简单的剪枝(剪枝原则见代码注释)。详细步骤如下:

  1. 首先计算字符串中最大合法左括号/右括号个数:右括号出现在左括号之前即为非法,多余的左括号亦为非法,左右括号顺序抵消
  2. 其次使用递归遍历原字符串的每一个元素,根据左右括号合法匹配的原则以及最大合法左右括号个数判断是否需要取当前元素进入目标字符串,取和不取分别对应两条递归搜索路径。

代码

class Solution {
    private void recu(String s, String cur, int ptr, int cur_left, int cur_right, int tar_left, Set<String> ans) {
        int n = s.length();
        if (ptr == n) {
            if (cur_left == tar_left && cur_right == tar_left) {
                ans.add(cur);
            }
            return;
        }
        if (n - ptr < 2 * tar_left - cur_left - cur_right) {        
           return;  // insufficient chars
        }
        if (cur_left - cur_right > n - ptr) {
            return; // insufficient right brackets
        }
        char ch = s.charAt(ptr);
        if (ch == '(') {
            if (cur_left < tar_left) {
                recu(s, cur + "(", ptr + 1, cur_left + 1, cur_right, tar_left, ans);
            }
            recu(s, cur, ptr + 1, cur_left, cur_right, tar_left, ans);
        } else if (ch == ')') {
            if (cur_right < cur_left) {
                recu(s, cur + ")", ptr + 1, cur_left, cur_right + 1, tar_left, ans);
            }
            recu(s, cur, ptr + 1, cur_left, cur_right, tar_left, ans);
        } else {
            recu(s, cur + ch, ptr + 1, cur_left, cur_right, tar_left, ans);
        }
    }
    
    public List<String> removeInvalidParentheses(String s) {
        int invalid_left = 0, total_left = 0;
        for (char ch: s.toCharArray()) {
            if (ch == '(') {
                ++invalid_left;
                ++total_left;
            } else if (ch == ')') {
                if (invalid_left > 0) {
                    --invalid_left;
                }
            }
        }
        Set<String> ans = new HashSet<String>();
        recu(s, "", 0, 0, 0, total_left-invalid_left, ans);
        return new ArrayList<String>(ans);
    }
}

你可能感兴趣的:(LeetCode,LeetCode,Hard,Java,搜索,剪枝)