[回溯算法]leetcode216. 组合总和 III(c实现)

举报
lovevivi 发表于 2022/11/24 08:58:49 2022/11/24
【摘要】 题目找出所有相加之和为 n 的 k 个数的组合,且满足下列条件:只使用数字1到9每个数字 最多使用一次 返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次,组合可以以任何顺序返回。示例 1:输入: k = 3, n = 7输出: [[1,2,4]]解释:1 + 2 + 4 = 7没有其他符合的组合了。示例 2:输入: k = 3, n = 9输出: [[1,2,6], [1,3...

题目

找出所有相加之和为 n 的 k 个数的组合,且满足下列条件:
只使用数字1到9
每个数字 最多使用一次 
返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次,组合可以以任何顺序返回。
示例 1:
输入: k = 3, n = 7
输出: [[1,2,4]]
解释:
1 + 2 + 4 = 7
没有其他符合的组合了。
示例 2:
输入: k = 3, n = 9
输出: [[1,2,6], [1,3,5], [2,3,4]]
解释:
1 + 2 + 6 = 9
1 + 3 + 5 = 9
2 + 3 + 4 = 9
没有其他符合的组合了。
示例 3:
输入: k = 4, n = 1
输出: []
解释: 不存在有效的组合。
在[1,9]范围内使用4个不同的数字,我们可以得到的最小和是1+2+3+4 = 10,因为10 > 1,没有有效的组合。

代码

int *path;
int pathTOP;
int**ans;
int ansTOP;
void backtracking(int targetsum,int k,int sum,int satrtindex)
{
     int i =0;
    if(sum> targetsum)//剪枝操作
    {
        return;
    }
    if(k==pathTOP)
    {
        if(sum == targetsum)
        {
         int *temp=(int*)malloc(sizeof(int)*k);
          for(i=0;i<k;i++)
          {
             temp[i]=path[i];
          }
          ans[ansTOP++]=temp;
        }
        return;
    }
    for(i=satrtindex;i<=9-(k-pathTOP)+1;i++)
    {
        sum+=i;
        path[pathTOP++]=i;
        backtracking( targetsum,k,sum,i+1);
        sum-=i;
        pathTOP--;
    }
}
int** combinationSum3(int k, int n, int* returnSize, int** returnColumnSizes){
    path=(int*)malloc(sizeof(int)*k);
    ans=(int**)malloc(sizeof(int*)*10000);
    pathTOP=0;
    ansTOP=0;
    int sum=0;
    backtracking(n,k,sum,1);
    *returnSize=ansTOP;
    *returnColumnSizes=(int*)malloc(sizeof(int)*(*returnSize));
    int i=0;
    for(i=0;i<(*returnSize);i++)
    {
        (*returnColumnSizes)[i]=k;
    }
    return ans;
}

过程分析

设置在外层return返回的原因

image.png

当 取 1 2 3 时
k=3,sum=1+2+3=6时,由于n题中要求符合n=7,而 sum<tragsum
对应进入递归终止条件中,
但tragsum<n所以需要在外面设置return 返回上一层,
此时的 sum 需要减去 这一层的 i的值3 即 sum=sum-3=1+2
image.png

正确传入

image.png

当取 1 2 4 时,
使用return返回到上一层后,取 4再次进入下一层
k=3,sum=1+2+4=7时,tragsum==sum,进入两层if循环后,将一维数组path的值
传入 ans二维数组中,返回时仍需要减去这一层i的值4即sum-4=1+2

剪枝操作

1.

image.png

当为 1 2 5时,
k=3,sum=1+2+5=8时,tragsum>sum,进入if循环,返回到上一层
,减去这一层i的值5 即 sum-5=1+2
image.png

2.

image.png

当取 1 2 3 4时,k=4,因为题中要求是k=3,所以不符合题意
为了删去不符合题意的枝条,所以在for循环中设置边界
image.png

剪枝操作范围的确定

1.

image.png

startindex默认为1,i=1开始,
假设 k=3,sum=7
pathTOP代表所选取的元素个数 (默认从0开始)

2.

image.png

k-pathTOP代表剩下还需要选取的元素个数
k=3 ,k-pathtOP=3

3.

image.png

n-i代表列表中的元素个数
n-i >= k-pathtOP

4.

image.png

i<=n-(k-pathTOP)+1
此时的i处于至多可以遍历的位置
因为 i默认从1开始,所以需要加上1,使其可以包括起始位置

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。