首页 > 编程语言 >[回溯算法]leetcode216. 组合总和 III(c实现)

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

时间:2022-11-12 11:03:59浏览次数:51  
标签:返回 pathTOP 组合 示例 int sum 回溯 III leetcode216

题目

找出所有相加之和为 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,使其可以包括起始位置

标签:返回,pathTOP,组合,示例,int,sum,回溯,III,leetcode216
From: https://blog.51cto.com/u_15787387/5846554

相关文章

  • 回溯算法解数独问题
    好久没写算法了,浅解个数独本篇代码以伪代码为主,主要讲解解题思路规则介绍:首先数独的游戏规则,每个九宫格每一行每一列每个数字只能出现一次(1-9)开局时会生成一些不......
  • 回溯算法dfs: lc46全排列 lc47全排列ll
    result=[] defbacktrack(路径,选择列表):if满足结束条件:result.add(路径)returnfor选择in选择列表:做选择backtrack(路径,选择列表)撤销选择 46全......
  • 广/深度优先搜索与回溯法
    深度优先搜索:在搜索到一个新的节点时,立即对该节点进行遍历;因此需用先入后出的栈,也可以通过与栈等价的递归来实现。深度优先搜索也可以用来检测环路:记录每个遍历过的节点的......
  • POJ-1417(带权并查集+01背包+回溯)
    TrueLiars题目描述:Peter有一个王国。在这个王国里,一共有2种人,即诚实人和撒谎人。诚实人永远说真话,撒谎人永远说假话。可惜的是,Peter只记得诚实人的数量和撒谎人的数量......
  • HDU 2216 Game III
    ProblemDescriptionZjtandSarawilltakepartinagame,namedGameIII.ZjtandSarawillbeinamaze,andZjtmustfindSara.Therearesomestrang......
  • 代码随想录day50 | 123.买卖股票的最佳时机III 188. 买卖股票的最佳时机 IV
    123.买卖股票的最佳时机III题目|文章思路相比于122.买卖股票的最佳时机III,这道题多了一道限制,就是买卖次数的限制,我的想法是通过增加一维来实现。文章中给出的方法则......
  • 代码随想录day48 | 198.打家劫舍 213.打家劫舍II 337.打家劫舍III
    198.打家劫舍题目|文章思路数组以及下标含义dp[j]:当偷到第j家时所能获得的最多的金钱递推公式dp[j]=max(dp[j-1],dp[j-2]+nums[i])当偷到第j家时,如果偷......
  • 第二十七天 | 回溯算法
    第二十七天,继续回溯算法 39.组合总和classSolution{List<Integer>list=newArrayList<>();List<List<Integer>>ans=newArrayList<>();in......
  • 回溯法
      关键实现:(体会递归与或语句的用法,以及局部静态变量的处理) ......
  • 回溯
    for循环横向遍历,递归纵向遍历,回溯不断调整结果集画树,回溯要画树77.组合给定两个整数n和k,返回范围[1,n]中所有可能的k个数的组合。你可以按任何顺序返回答......