NO.22 括号生成 中等
思路一:暴力法 1. 将2*n个括号的序列全部得到。2. 同时判断其是否为有效序列。如果是则加入结果集。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| List<String> res=new ArrayList<>(); public List<String> generateParenthesis(int n) { dfs(0,"",n); return res; }
public void dfs(int index,String conbination,int n){ if (index==2*n){ if (isValid(conbination))res.add(conbination); return; }else { dfs(index+1,conbination+'(',n); dfs(index+1,conbination+')',n); } }
public boolean isValid(String s){ int balance=0; for (int i=0;i<s.length();i++){ if (s.charAt(i)=='('){ balance++; }else { balance--; }
if (balance<0)return false; } return balance==0; }
|
时间复杂度:O(2^2n*n)
思路二:回溯法 该方法是对上面的暴力法的一个优化思路。上面的方法需要组合出所有的序列(有效的和无效的),思路就是不生成无效的序列(或者说是”剪枝”,剪除无效无效序列)。观察有效序列的特点:1. 因为是括号’对’,所以n对括号序列中的’(‘和’)’的数量都是n个。2. ‘)’不能出现在与其成对的’(‘之前。
针对上述细节,思考回溯算法细节:
- 当’(‘和’)’的数量都是n个的时候,说明已经得到括号序列。
- ‘(‘数量小于n的时候,可以向序列中继续添加’(‘。
- ‘)’数量小于n并且当前’)’数量小于当前’(‘数量时,才可以向序列中继续添加’)’。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| List<String> res=new ArrayList<>();
public List<String> generateParenthesis(int n) { dfs(0,0,"",n); return res; }
public void dfs(int l,int r,String combination,int n){
if (l==n&&r==n){ res.add(combination); return; }
if (l<n){ dfs(l+1,r,combination+'(',n); }
if (r<n&&r<l){ dfs(l,r+1,combination+')',n); } }
|
时间复杂度:O(4^n/sqrt(n))。在回溯过程中,每个有效序列最多需要n步。
本人菜鸟,有错误请告知,感激不尽!
更多题解和学习记录博客:博客、github