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

举报
lovevivi 发表于 2022/11/24 08:59:37 2022/11/24
【摘要】 输出:[[1,2,2],[5]] 代码/** * Return an array of arrays of size *returnSize. * The sizes of the arrays are returned as *returnColumnSizes array. * Note: Both returned array and *columnSizes array must b...

输出:
[
[1,2,2],
[5]
]

代码

/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */
 int *path;
 int pathTOP;
 int **ans;
 int  ansTOP;
 int *length;
 void backtracking(int*candidates,int candidatesSize,int target,int sum,int startindex)
 {
     int i=0;
     if(sum>target)
     {
         return ;
     }
     //递归终止条件
     if(sum==target)
     {
        int*temp=(int*)malloc(sizeof(int)*pathTOP);
        for(i=0;i<pathTOP;i++)
        {
          temp[i]=path[i];
        }
         ans[ansTOP]=temp;
         length[ansTOP++]=pathTOP;
         return ;
     }
     for(i=startindex;i<candidatesSize;i++)
     {
         if(i>startindex&&candidates[i-1]==candidates[i])
         //判断是否用于去重,若为树层则需去重
         {
             continue;
         }
         path[pathTOP++]=candidates[i];
         sum+=candidates[i];
         backtracking(candidates,candidatesSize,target,sum,i+1);
         //回溯
         sum-=candidates[i];
         pathTOP--;
     }
 }
 int cmp(const void*e1,const void*e2)
 {
     return *((int*)e1)-*((int*)e2);
 }
int** combinationSum2(int* candidates, int candidatesSize, int target, int* returnSize, int** returnColumnSizes){
      path=(int*)malloc(sizeof(int)*50);
      ans=(int**)malloc(sizeof(int*)*200);
      length=(int*)malloc(sizeof(int)*200);
      pathTOP=0;
      ansTOP=0;
      int sum=0;//用于记录取值的加和,与traget判断
      int startindex=0;//用于记录起始位置
      qsort(candidates,candidatesSize,sizeof(int),cmp);
      backtracking(candidates,candidatesSize,target,sum,startindex);
      *returnSize=ansTOP;
      //记录每个集合中的大小
      *returnColumnSizes=(int*)malloc(sizeof(int)*ansTOP);
      int i=0;
      for(i=0;i<ansTOP;i++)
      {
          (*returnColumnSizes)[i]=length[i];
      }
       return ans;
}

过程

1.为什么要有去重操作

若不包括去重操作,那也就没有排序操作
image.png
因为组合是不分顺序的,所以像出现的 1 2 5 与 2 1 5实际是表示一个组合

2.分辨树层重复还是树层与树枝重复

这里以 1 1 2为例
我们要区分是树层的重复还是 树层与树枝的重复
image.png

这里产生了两个 1 2 组合
第一个 1 2 组合:
image.png
先在树层中取1,for循环中剩下 1 2 ,进入递归中,取树枝的1
这种 即为树层与树枝的重复 ,即便是两者值相同也不用去重

第二个 1 2 组合:
image.png
取树层的1后,发现再次进入for循环中,i=2,startindex仍等于1
i>startindex 同时 两者值相同 即判断树层中重复,需要去重

3.递归展开图

image.png

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

评论(0

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

全部回复

上滑加载中

设置昵称

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

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

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