力扣心得(四)--回溯:组合总和

今天写的是力扣低216题,组合总和|||(不会打)

来看题干:在数字1~9中找出所有相加之和为 n 的 k 个数的组合(元素不可重复使用)

这是一个组合问题 ==> 回溯

回溯的步骤如下:(具体的可以看我发的力扣心得(三))

1.声明全局变量,写操作函数的大纲

#include <stdlib.h>
static int** ans;    // 结果数组(二维数组)
static int* ansSize; // 储存结果数组指针长度的数组
static int* path;    // 路径数组
static int pathTop;  // 路径数组当前长度
static int ansTop;   // 结果数组当前长度

void backtracking()
{

}

int** combinationSum3(int k, int n, int* returnSize, int** returnColumnSizes) {
    // 1.申请内存
    ans = (int**)malloc(1000 * sizeof(int*));
    ansSize = (int*)malloc(1000 * sizeof(int));
    path = (int*)malloc(k * sizeof(int));

    // 2.初始化参数
    ansTop = 0;
    pathTop = 0;

    // 3.进入递归
    void backtracking()

    // 4.返回参数
    *returnSize = ansTop;
    *returnColumnSizes = ansSize;

    // 5.返回结果
    return ans;
}

2.画树形结构图

3.找终止条件和结构储存条件

看树状图:

终止条件:路径数达到k

储存条件:路径数总和为n

4.开始写递归函数

先来定参数:

1.肯定得有k和n和路径总和,不然无法写终止和存储条件
2.得有index,不然不知道现在遍历到哪个数了
那for 循环呢
我们的起点是目前遍历的数,也就是index【所以 i = index】
其次,我们的终点是数字9【所以是i <= 9】
最后,我们是要一个数一个数的遍历【所以是i++】
okok,那代码基本已经出来了

void backtracking(int k, int n, int sum, int index)
{
    // 终止条件:路径长度为k
    if (pathTop == k)
    {
        // 储存条件:路径总和为n
        if (sum == n)
        {
            // 因为我们要把满足条件的路径复制到返回数组中,所以要先申请内存(长度就是路径数组的长度)
            ans[ansTop] = (int*)malloc(pathTop * sizeof(int));
            for (int i = 0; i < pathTop; i++)
            {
                ans[ansTop][i] = path[i];
            }
            // 更新ansSize和ansTop的数据
            ansSize[ansTop++] = pathTop;
        }
        // 最后别忘记return
        return;
    }

    for (int i = index; i <= 9; i++)
    {
        // 把遍历到的数放入路径数组
        path[pathTop++] = i;
        sum += i;
        // 进入递归
        backtracking(k, n, sum, i + 1);
        // 撤回选择,恢复现场
        pathTop--;
        sum -= i;
    }
}

最后把操作函数中的递归部分补齐即可

int** combinationSum3(int k, int n, int* returnSize, int** returnColumnSizes) {
    // 1.申请内存
    ans = (int**)malloc(1000 * sizeof(int*));
    ansSize = (int*)malloc(1000 * sizeof(int));
    path = (int*)malloc(k * sizeof(int));

    // 2.初始化参数
    ansTop = 0;
    pathTop = 0;

    // 3.进入递归(就动了这里的参数)
    backtracking(k, n, 0, 1);

    // 4.返回参数
    *returnSize = ansTop;
    *returnColumnSizes = ansSize;

    // 5.返回结果
    return ans;
}

来看看完整代码

#include <stdlib.h>

static int** ans;    // 结果数组(二维数组)
static int* ansSize; // 储存结果数组指针长度的数组
static int* path;    // 路径数组
static int pathTop;  // 路径数组当前长度
static int ansTop;   // 结果数组当前长度

void backtracking(int k, int n, int sum, int index)
{
    // 终止条件:路径长度为k
    if (pathTop == k)
    {
        // 储存条件:路径总和为n
        if (sum == n)
        {
            // 因为我们要把满足条件的路径复制到返回数组中,所以要先申请内存(长度就是路径数组的长度)
            ans[ansTop] = (int*)malloc(pathTop * sizeof(int));
            for (int i = 0; i < pathTop; i++)
            {
                ans[ansTop][i] = path[i];
            }
            // 更新ansSize和ansTop的数据
            ansSize[ansTop++] = pathTop;
        }
        // 最后别忘记return
        return;
    }

    for (int i = index; i <= 9; i++)
    {
        // 把遍历到的数放入路径数组
        path[pathTop++] = i;
        sum += i;
        // 进入递归
        backtracking(k, n, sum, i + 1);
        // 撤回选择,恢复现场
        pathTop--;
        sum -= i;
    }
}

int** combinationSum3(int k, int n, int* returnSize, int** returnColumnSizes) {
    // 1.申请内存
    ans = (int**)malloc(1000 * sizeof(int*));
    ansSize = (int*)malloc(1000 * sizeof(int));
    path = (int*)malloc(k * sizeof(int));

    // 2.初始化参数
    ansTop = 0;
    pathTop = 0;

    // 3.进入递归
    backtracking(k, n, 0, 1);

    // 4.返回参数
    *returnSize = ansTop;
    *returnColumnSizes = ansSize;

    // 5.返回结果
    return ans;
}

提交!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱吃葱的羊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值