华为面试题:求n对括号的所有合法表达式(两种简洁做法)

来源:互联网 发布:济南seo小武 编辑:程序博客网 时间:2024/04/27 16:02

这个题目其实以前写过,但是现在再看,有了简洁有效的多的解法:一个DFS就搞定了。

def construct(n):    def create(num1,num2,exp):        if num1+num2==2*n:assert(num1==n);print(exp)        if num1<n :create(num1+1,num2,(exp+'(')[::])        if num1>num2:create(num1,num2+1,(exp+')')[::])    create(0,0,'')

同时可以分析一下n对括号的合法表达式有多少种?

F(n)=n1k=0F(k)F(n1k),具体思路就是用更小的括号构造出更多的括号,但是为什么是n-1-k呢,因为两边的括号可能会因为对称而重复比如:

()()()|()()|()()(),

所以人为的为左边的表达式外层添加一个括号,这样就保证不会重复了。所以只需要构造n-k-1个括号即可。如:

(()())|()(())|()()因为我特意添加的括号,保证不会出现不同的构造方法对应相同的表达式。

根据这个思路,可以更快的求出n对括号的所有合法表达式,测试了一下发现速度比上面的快5倍左右,有点类似于动态规划的思路。但是不是求最优解。

def quick_construct(n):    ans = {0:[''],1:['()']}    for num in range(2,n+1):        for k in range(0,num):            for first in ans[k]:                ans.setdefault(num,[]).extend \                (['('+first+')'+second for second in ans[num-k-1]])    return '\n'.join(ans[n])
0 0