Remove Invalid Parentheses - LeetCode

Remove Invalid Parentheses - LeetCode

题目
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 ).

Examples:
"()())()" -> ["()()()", "(())()"]
"(a)())()" -> ["(a)()()", "(a())()"]
")(" -> [""]


给出一串含有'('')'以及其他字符的字符串,去掉最少的括号使字符串变成合法的,给出所有可能的结果。
偷瞄了一下答案,下面是我对答案理解。。

首先要知道去掉多少才能算是最少,
如果有一种方法能够只去掉一个'('就使字符串变得合法,那么去掉两个'('和一个')'的方法就不能算是最少的。(注意这里如果要增加去掉的括号就必须成对增加)

所以我们希望找出所能去掉的括号的最少个数,下面的代码就起到了这个作用

int leftrm, rightrm;
leftrm = rightrm = 0;
for (int i = 0; i < s.length(); i++) {
    if (s[i] == '(') {
        leftrm++;
    } else if (s[i] == ')') {
        if (leftrm > 0) leftrm--;
        else rightrm++;
    }
}

leftrm记录了需要去掉的左括号的个数,right记录了需要去掉的右括号的个数。
显然,按照上面的方法去掉括号,一定能形成合法的字符串,但是为什么按这个方法去掉的括号数就是最少的呢?

上面的算法可以看成一个动态规划,第i(i从0开始数)次循环中的leftem记录了s中前i+1个字符组成的字符串(为了形成合法的串)所需要去掉的左括号的最少个数,rightrm类似。可以自己逐步推理一下,详细的就不说了

当我们知道了所需要去掉的括号的最少个数之后就可以用遍历的方法了
(这里说一下为什么还需要遍历,因为就算去掉的括号的个数定了下来,所去括号的位置还可能是不同的,去掉不同位置的括号可能形成不同的结果,所以需要遍历一下所有情况)
如何遍历?对于每一个字符,都有去掉不去掉两种选择,这就可以形成一颗二叉树。
然后根据上面求出的leftrm, rightrm以及一些其他限制条件限制搜索的情况。

下面是完整代码

class Solution {
public:
    vector<string> removeInvalidParentheses(string s) {
        unordered_set<string> results;
        int leftrm, rightrm;
        leftrm = rightrm = 0;
        for (int i = 0; i < s.length(); i++) {
            if (s[i] == '(') {
                leftrm++;
            } else if (s[i] == ')') {
                if (leftrm > 0) leftrm--;
                else rightrm++;
            }
        }
        helper(s, leftrm, rightrm, 0, 0, "", results);
        for (unordered_set<string>::iterator it = results.begin(); it != results.end(); it++) {
            cout << *it << endl;
        }
        return vector<string>(results.begin(), results.end());
    }
    void helper(string s, int leftrm, int rightrm, int index, int pair, string path, unordered_set<string> & results) {
        if (leftrm == 0 && rightrm == 0 && pair == 0 && index == s.length()) {
            results.insert(path);
            return;
        }
        if (index < s.length()) {
            if (s[index] != '(' && s[index] != ')') {
                helper(s, leftrm, rightrm, index+1, pair, path+s[index], results);
            }
            if (s[index] == '(') {
                if (leftrm > 0) {
                    helper(s, leftrm-1, rightrm, index+1, pair, path, results);
                }
                helper(s, leftrm, rightrm, index+1, pair+1, path+s[index], results);
            }
            if (s[index] == ')') {
                if (rightrm > 0) {
                    helper(s, leftrm, rightrm-1, index+1, pair, path, results);
                }
                if (pair > 0) {
                    helper(s, leftrm, rightrm, index+1, pair-1, path+s[index], results);
                }
            }
        }
    }
};

猜你喜欢

转载自blog.csdn.net/sgafpzys/article/details/78885641