22. Generate Parentheses

产生各种合法的括号组合。比如(()())(),((()))

DFS recursion. 括号是成对的,所以dfs函数有两个分支,一个加(,一个加)。

class Solution:
    def generateParenthesis(self, n: int) -> List[str]:
        result = []
        if n>0:
            self.dfs(n, n, "", result)
        return result
        
    def dfs(self, l_available, r_available, item, result):
        if l_available >r_available:  # right ) is used faster, wrong!
            return
        if l_available==0 and r_available==0:
            result.append(item)
            return
        if l_available>0:
            self.dfs(l_available-1, r_available, item+'(', result)
        if r_available>0:
            self.dfs(l_available, r_available-1, item+')', result)

参考了Michelle和花花酱的解说。这道题看似简单,其实还是有trick的。

打印了n=3的calling stack,如下所示。

l_available=3, r_available=3, item=
Calling left
l_available=2, r_available=3, item=(
Calling left
l_available=1, r_available=3, item=((
Calling left
l_available=0, r_available=3, item=(((
Calling right
l_available=0, r_available=2, item=((()
Calling right
l_available=0, r_available=1, item=((())
Calling right
l_available=0, r_available=0, item=((()))
Ret from right
Ret from right
Ret from right
Ret from left
Calling right
l_available=1, r_available=2, item=(()
Calling left
l_available=0, r_available=2, item=(()(
Calling right
l_available=0, r_available=1, item=(()()
Calling right
l_available=0, r_available=0, item=(()())
Ret from right
Ret from right
Ret from left
Calling right
l_available=1, r_available=1, item=(())
Calling left
l_available=0, r_available=1, item=(())(
Calling right
l_available=0, r_available=0, item=(())()
Ret from right
Ret from left
Calling right
l_available=1, r_available=0, item=(()))
Illegal. Forget it.
Ret from right
Ret from right
Ret from right
Ret from left
Calling right
l_available=2, r_available=2, item=()
Calling left
l_available=1, r_available=2, item=()(
Calling left
l_available=0, r_available=2, item=()((
Calling right
l_available=0, r_available=1, item=()(()
Calling right
l_available=0, r_available=0, item=()(())
Ret from right
Ret from right
Ret from left
Calling right
l_available=1, r_available=1, item=()()
Calling left
l_available=0, r_available=1, item=()()(
Calling right
l_available=0, r_available=0, item=()()()
Ret from right
Ret from left
Calling right
l_available=1, r_available=0, item=()())
Illegal. Forget it.
Ret from right
Ret from right
Ret from left
Calling right
l_available=2, r_available=1, item=())
Illegal. Forget it.
Ret from right
Ret from right
Ret from left
Calling right
l_available=3, r_available=2, item=)
Illegal. Forget it.
Ret from right
[’((()))’, ‘(()())’, ‘(())()’, ‘()(())’, ‘()()()’]

你可能感兴趣的:(算法题)