[LeetCode]301. Remove Invalid Parentheses

301. Remove Invalid Parentheses

题意:删除最少的无效的括号,使得字符串符合规范。

DFS

思路:先记录需要删除的左括号和右括号,然后遇到左括号就删,遇到右括号就删,分别删到不能再删,考虑递归的各种情况,符合规范则加入。

class Solution(object):
    def removeInvalidParentheses(self, s):
        """
        :type s: str
        :rtype: List[str]
        """
        def isvalid(string):
            if not string:
                return True
            k = 0
            for n in string:
                if n == '(':
                    k += 1
                elif n == ')':
                    if not k:
                        return False
                    k -= 1
            return k == 0
        def dfs(index, left_remove, right_remove, path):
            if index == len(s):
                if not left_remove and not right_remove and isvalid(path) and path not in res:
                    res.append(path)
                return
            if s[index] not in '()':
                dfs(index + 1, left_remove, right_remove, path + s[index])
            else:
                if s[index] == '(':
                    if left_remove:
                        dfs(index + 1, left_remove - 1, right_remove, path)
                    dfs(index + 1, left_remove, right_remove, path + s[index])
                else:
                    if right_remove:
                        dfs(index + 1, left_remove, right_remove - 1, path)
                    dfs(index + 1, left_remove, right_remove, path + s[index])
        res = []
        left_remove, right_remove = 0, 0
        for n in s:
            if n == '(':
                left_remove += 1
            elif n == ')':
                if left_remove:
                    left_remove -= 1
                else:
                    right_remove += 1
        dfs(0, left_remove, right_remove, '')
        return res

其实只需要一个变量pair来记录对应的括号数,加上左括号则加1,加上右括号则减1,保证最后为0,则说明左右括号是两两对应的。

class Solution(object):
    def removeInvalidParentheses(self, s):
        """
        :type s: str
        :rtype: List[str]
        """
        def dfs(index, left_remove, right_remove, pair, path):
            if index == len(s):
                if not left_remove and not right_remove and not pair:
                    res.add(path)
                return
            if s[index] not in '()':
                dfs(index + 1, left_remove, right_remove, pair, path + s[index])
            else:
                if s[index] == '(':
                    if left_remove:
                        dfs(index + 1, left_remove - 1, right_remove, pair, path)
                    dfs(index + 1, left_remove, right_remove, pair + 1, path + s[index])
                else:
                    if right_remove:
                        dfs(index + 1, left_remove, right_remove - 1, pair, path)
                    if pair:
                        dfs(index + 1, left_remove, right_remove, pair - 1, path + s[index])
        res = set()
        left_remove, right_remove = 0, 0
        for n in s:
            if n == '(':
                left_remove += 1
            elif n == ')':
                if left_remove:
                    left_remove -= 1
                else:
                    right_remove += 1
        dfs(0, left_remove, right_remove, 0, '')
        return list(res)

暴力

还有一种方法,暴力,相比上面来说这种方法要低效的多,因为并不考虑删除的是左括号还是右括号,各种删,最后从这些结果中找出符合规范的,注意只要该层找到以后,就不再找了,保证删除最少的括号,如下:

class Solution(object):
    def removeInvalidParentheses(self, s):
        """
        :type s: str
        :rtype: List[str]
        """
        if not s:
            return [""]
        queue = collections.deque()
        queue.append(s)
        visited = set([s])
        res = []
        isDone = False
        while queue:
            cur = queue.pop()
            if self.isValid(cur):
                res.append(cur)
                isDone = True
            if not isDone:
                for i in range(len(cur)):
                    if cur[i] == '(' or cur[i] == ')':
                        new = cur[:i] + cur[i + 1:]
                        if new not in visited:
                            visited.add(new)
                            queue.appendleft(new)
        return res
    def isValid(self, string):
        total = 0
        for s in string:
            if s == '(':
                total += 1
            elif s == ')':
                total -= 1
            if total < 0:
                return False
        return total == 0
posted @ 2017-09-06 11:48  banananana  阅读(292)  评论(0编辑  收藏  举报