22. 括号生成

177 阅读1分钟

题目描述

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

示例

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

示例 2:
输入:n = 1
输出:["()"]

提示:
1 <= n <= 8

来源:力扣(LeetCode)
链接:leetcode-cn.com/problems/ge…

分析

找所有组合,与17. 电话号码的字母组合类似

实现

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
void backTracing(char **res, char *str, int n, int *returnSize, int idx, int left, int right)
{
    if (idx == 2 * n) {    // 已经匹配到叶子节点,将组合放入结果集中
        res[*returnSize] = (char*)malloc(sizeof(char) * (2 * n + 1));
        strcpy(res[*returnSize], str);
        (*returnSize)++;
    }
    
    // 如果左括号的数量小于n,那么可以放一个左括号
    if (left < n) {
        str[idx] = '(';
        backTracing(res, str, n, returnSize, idx + 1, left + 1, right);
    }

    // 如果右括号的数量小于左括号,那么可以放置右括号
    if (left > right) {
        str[idx] = ')';
        backTracing(res, str, n, returnSize, idx + 1, left, right + 1);
    }
}

// 根据题意找到所有的组合,用回溯算法
char **generateParenthesis(int n, int *returnSize)
{
    // 括号n对可能的组合数为1430。根据卡特兰数得出,感兴趣的自行搜索
    char **res = (char**)malloc(sizeof(char*) * 1430);
    memset(res, 0, sizeof(char*) * 1430);
    char *str = (char*)malloc(sizeof(char) * (2 * n + 1));
    memset(str, 0, sizeof(char) * (2 * n + 1));    // 内存一定要初始化,不然后面结束符也要自己加。

    *returnSize = 0;
    backTracing(res, str, n, returnSize, 0, 0, 0);
    return res;
}