代码随想录day25 回溯算法 LC.77组合

文章介绍了使用回溯算法解决组合问题的方法,通过递归避免大循环,并利用二级指针管理结果。在递归过程中,当找到一个组合时将其添加到答案数组。同时,提出了剪枝策略以提高效率,如当无法达到所需组合数量时提前终止遍历。
摘要由CSDN通过智能技术生成

回溯

组合中按暴力解法来的话如果k太大会造成for循环嵌套太多,用递归来代替,每层递归嵌套一个for循环
注意递归的顺序,return一次返回上一次递归,该代码中for循环结束了也返回上一次递归。
注意
下代码中递归时参数是j+1以便继续向下追踪而不能是startindex+1

for(j = startindex;j<=n;j++)
    {
        line[linetop++] = j;
        wayback(k,n,j+1);
        linetop--;
    }
int* line;
int linetop;
int** ans;
int anstop;

void wayback(int k,int n,int startindex)
{
    //一个组合已经找到了,把它加入到答案数组里面去
    if(linetop == k)
    {
        int* temp = (int*)malloc(sizeof(int)*k);
        for(int i = 0;i<k;i++)
        {
            temp[i] = line[i];
        }
        ans[anstop++] = temp;
        return ;//返回上一层继续往下找
    }

    int j;
    for(j = startindex;j<=n;j++)
    {
        line[linetop++] = j;
        wayback(k,n,j+1);
        linetop--;
    }
}

int** combine(int n, int k, int* returnSize, int** returnColumnSizes){
    line = (int*)malloc(sizeof(int)*k);
    ans = (int**)malloc(sizeof(int*)*1000);
    linetop = 0;
    anstop = 0;
    wayback(k,n,1);
    *returnSize = anstop;
    //returnColumnSizes数组存储ans二维数组对应下标中一维数组的长度(都为k)
    *returnColumnSizes = (int*)malloc(sizeof(int) *(*returnSize));
    int i;
    for(i = 0; i < *returnSize; i++) {
        (*returnColumnSizes)[i] = k;
    }
    //返回ans二维数组
    return ans;
}

对类似题目中函数里面二级指针的初步理解

如下是调用该函数的main函数,函数参数里面的而及指针指向的其实是一维数组,记录每一行有几列。

int main(){
    int n = 4, k = 2;
    int returnSize;
    int* returnColumnSizes;
    int** ans = combine(n, k, &returnSize, &returnColumnSizes);
    for(int i = 0; i < returnSize; i++){
        for(int j = 0; j < k; j++){
            printf("%d ", ans[i][j]);
        }
        printf("\n");
    }
    return 0;
}

剪枝

到后面几个到不了k个,可以直接就不遍历如n=5,k=3,345可以组成,从4开始只有两个无法组成组合。
再往下层也是同理,从某个位置往后就无法成功到达所需要的个数
可将

for(j = startindex;j<=n;j++)
    {
        line[linetop++] = j;
        wayback(k,n,j+1);
        linetop--;
    }

改为

for(j = startIndex; j <= n- (k - pathTop) + 1;j++) {
        //将当前结点放入path数组
        path[pathTop++] = j;
        //进行递归
        backtracking(n, k, j + 1);
        //进行回溯,将数组最上层结点弹出
        pathTop--;
    }
    ```
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值