22. Generate Parentheses

以一个"()"为一个单位,往之前的左、中、右里面插,肯定是不行的。因为有重复的形式,需要剔除,很是麻烦。

正确思路是一个半括号一个半括号的添加。

添加的时候为了保证添加下去是符合括号规律的,必须满足,在现有基础上:

  • 左括号的数量 < n
  • 右括号的数量 <= 左括号的数量

这样,当右括号的数量 == n就表示没法继续添加了,说明此时是一个解。

public class Solution {
    public List<String> generateParenthesis(int n) {
        List<String> res = new ArrayList<String>();
        if(n == 0) return res;

        
        helper(res,n,0,0,new String());
        return res;
    }
    
    public void helper(List<String> res, int n, int L, int R,String tempStr)
    {
        //System.out.println(tempStr + " " + L + " " + R);
        if(R == n)
        {
            res.add(tempStr);
        }
        else
        {
            if(R < L)
            {
                helper(res,n,L,R+1,tempStr+")");
            }
            if(L < n)
            {
                helper(res,n,L+1,R,tempStr+"(");
            }
        }
    }
}

上面的是二刷的结果。
一刷的时候做的很蠢,用的判断是,总数==现有半括号的2倍,然后再进行判断现有的括号是不是valid,比如N=4 ((((也会判断一下。
二刷的判断就聪明多了,不会生成错误的组合。可喜可贺。。至少在蠢逼的基础上进步了一点。。



三刷。

右括号数量永远不大于左括号数量。
左括号数量永远不大于N。
根据这个2个来DFS剪枝。

重点

时间复杂度按理说是2^n,显而易见。。但是有说法是加上限制条件是n!,有可能……

Time: O(n!)
space: O(n)

public class Solution {
    public List<String> generateParenthesis(int n) {
        List<String> res = new ArrayList<>();
        if (n == 0) return res;
        dfs(res, n, new String(), 0, 0);
        return res;
    }
    
    public void dfs(List<String> res, int n, String tempS, int l, int r) {
        if (l + r == 2*n) {
            if (l == r)
                res.add(tempS);
            return;
        } else {
            if (l + 1 <= n) {
                String s1 = new String(tempS + "(");
                dfs(res, n, s1, l + 1, r);
            }
            if (r + 1 <= l) {
                String s2 = new String(tempS + ")");
                dfs(res, n, s2, l, r + 1);
            }
            return;
        }
    }
}
posted @ 2016-11-08 11:20  哇呀呀..生气啦~  阅读(119)  评论(0)    收藏  举报