leetcode_括号生成

79 阅读1分钟

数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。

示例 1:

输入: n = 3
输出: ["((()))","(()())","(())()","()(())","()()()"]

示例 2:

输入: n = 1
输出: ["()"]
//每一个括号组合都是以 ( 开头,
//对于对数为 n 的括号,
//可由对数为 n-1 的括号生成,
//生成方式为:  第 n 对括号 在开头,剩下的 n-1 对括号,要么在第n对括号的内部,要么在第n对括号的右侧
//即: dp[n]=(dp[p])+dp[q] ,且p+q=n-1
func generateParenthesis(n int) []string {
	var dp = make(map[int][]string)
	dp[0] = []string{""}
	dp[1] = []string{"()"}

	for i := 2; i <= n; i++ {

		for j := 0; j <= i-1; j++ {
			p := j
			q := i - 1 - p

			for _, pItem := range dp[p] {
				for _, qItem := range dp[q] {
					temp := fmt.Sprintf("(%s)%s", pItem, qItem)
					dp[i] = append(dp[i], temp)
				}
			}
		}
	}
	return dp[n]
}
//剩余左括号总数要小于等于右括号。 递归把所有符合要求的加上去就行了
class Solution {
        List<String> res = new ArrayList<>();
        public List<String> generateParenthesis(int n) {
            if(n <= 0){
                return res;
            }
            getParenthesis("",n,n);
            return res;
        }

        private void getParenthesis(String str,int left, int right) {
            if(left == 0 && right == 0 ){
                res.add(str);
                return;
            }
            if(left == right){
                //剩余左右括号数相等,下一个只能用左括号
                getParenthesis(str+"(",left-1,right);
            }else if(left < right){
                //剩余左括号小于右括号,下一个可以用左括号也可以用右括号
                if(left > 0){
                    getParenthesis(str+"(",left-1,right);
                }
                getParenthesis(str+")",left,right-1);
            }
        }
    }