22-m-Generate Parentheses

生成n对匹配的括号。逻辑也挺明显的,跟电话号码那题有点像,递归解决。不同的是本题要用n来控制左括号和右括号数目,基本思路是同层优先进左括号,然后右括号,有点像二叉树的中序遍历。仍然要注意递归时控制层次的参数要在传参时加1而不能在函数体内加1。

//另外本题用c完成,仍然没有做到内存动态分配,realloc老出错,只能预先分配一个大内存。

后来改进了下实现了内存动态分配,realloc出错在于result没用三重指针持有,如果realloc的result是新地址那么递归回退后随着函数被释放掉了,所以要用三重指针持有一下c中的字符串数组。代码在最后。

如下:

void backTrackingParenthesis(char **result, int *returnSize, int leftP, int rightP, int n) {
    if (leftP == n) {
        while (n - rightP > 0) {
            result[(*returnSize)][leftP + rightP] = ')';
            rightP++;
        }
        result[*returnSize][2 * n] = '\0';
        *returnSize += 1;
        strcpy(result[(*returnSize)], result[(*returnSize - 1)]);
        return;
    }
    if (leftP < n) {
        result[*returnSize][leftP + rightP] = '(';
        backTrackingParenthesis(result, returnSize, leftP + 1, rightP, n);
    }
    if (rightP < leftP) {
        result[*returnSize][leftP + rightP] = ')';
        backTrackingParenthesis(result, returnSize, leftP, rightP + 1, n);
    }
}
char** generateParenthesis(int n, int* returnSize) {
    if (n == 0)
        return NULL;
    int rsize = 10000;
    char **result = (char **)malloc(sizeof(char *) * rsize);
    memset(result, 0, sizeof(char *) * rsize);
    for (int i = 0; i < rsize; i++) {
        result[i] = (char *)malloc(sizeof(char) * (2 * n + 1));
        memset(result[i], 0, sizeof(char) * (2 * n + 1));
    }
    *returnSize = 0;
    int leftP = 0, rightP = 0;
    
    backTrackingParenthesis(result, returnSize, leftP, rightP, n);
    
    return result;
}

动态分配,已AC:

void backTrackingParenthesis(char ***result, int *returnSize, int leftP, int rightP, int n) {
    if (leftP == n) {
        while (n - rightP > 0) {
            (*result)[(*returnSize)][leftP + rightP] = ')';
            rightP++;
        }
        (*result)[*returnSize][2 * n] = '\0';
        *returnSize += 1;
        
        *result = (char **)realloc(*result, sizeof(char *) * (*returnSize + 1));
        (*result)[*returnSize] = (char *)malloc(sizeof(char) * (2 * n + 1));
        memset((*result)[*returnSize], 0, sizeof(char) * (2 * n + 1));
        
        strcpy((*result)[(*returnSize)], (*result)[(*returnSize - 1)]);
        return;
    }
    if (leftP < n) {
        (*result)[*returnSize][leftP + rightP] = '(';
        backTrackingParenthesis(result, returnSize, leftP + 1, rightP, n);
    }
    if (rightP < leftP) {
        (*result)[*returnSize][leftP + rightP] = ')';
        backTrackingParenthesis(result, returnSize, leftP, rightP + 1, n);
    }
}
char** generateParenthesis(int n, int* returnSize) {
    if (n == 0)
        return NULL;
    int rsize = 1;
    char **result = (char **)malloc(sizeof(char *) * rsize);
    memset(result, 0, sizeof(char *) * rsize);
    for (int i = 0; i < rsize; i++) {
        result[i] = (char *)malloc(sizeof(char) * (2 * n + 1));
        memset(result[i], 0, sizeof(char) * (2 * n + 1));
    }
    *returnSize = 0;
    int leftP = 0, rightP = 0;
    
    char ***tripleR = &result;
    
//    backTrackingParenthesis(result, returnSize, leftP, rightP, n);
    backTrackingParenthesis(tripleR, returnSize, leftP, rightP, n);
    
    return result;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值