首页 > 编程语言 >代码随想录算法训练营第22天-leetcode-回溯算法part01:

代码随想录算法训练营第22天-leetcode-回溯算法part01:

时间:2024-07-27 22:53:47浏览次数:23  
标签:malloc 22 int 个数 随想录 char 算法 ans path

#回溯算法理论基础

能解决的问题:

  • 组合问题:N个数里面按一定规则找出k个数的集合
  • 切割问题:一个字符串按一定规则有几种切割方式
  • 子集问题:一个N个数的集合里有多少符合条件的子集
  • 排列问题:N个数按一定规则全排列,有几种排列方式
  • 棋盘问题:N皇后,解数独等等

第77题. 组合

力扣题目链接(opens new window)

给定两个整数 n 和 k,返回 1 ... n 中所有可能的 k 个数的组合。

示例: 输入: n = 4, k = 2 输出: [ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4], 

注意:

1、对于是递归回溯问题,用树图来考虑问题!+使用基本结构

        同时,也要积极分析如何剪枝

2、路径类问题的标准套路

        在函数外开辟path 和 ans 一层空间 ans=(int**)malloc:一层空间,二层空间还没开辟

        终止条件 if(一条路径完成了) 把path放入ans数组

                先开辟ans的二层空间,ans【i】=(int*)malloc

                放入path的过程需要用循环一个个放入,直接=path的话,后面会随path修改而修改

        递归体:填充path

3、报错分析:

遇见heap堆错误,找malloc相关的;遇见stack栈报错,找函数内数组是否越界

4、returnsize 和 return column

*returnsize 在函数调用中无需&,且指向个数,而非下标

column的赋值过程:*column是正常数组,先为*column开辟空间,*column【第几个,<returnsize】=ans【第几个】有多少个二层元素

分析:

代码:

void bf(int *path,int n,int start,int k,int *pathlength,int **ans,int *returnSize){
    if(*pathlength == k-1){//路径类问题的标准输出
        ans[++(*returnSize)]=(int *)malloc(sizeof(int)*k);
        for (int i=0;i<k;i++){
            ans[*returnSize][i]=path[i];
        }

        return;
    }

    for(int i=start;i<=n-(k-*pathlength-2);i++){
        //遍历各个树
        //剪枝:如果后面全放进去,也达不到k个个数,那么就不考虑了
        path[++(*pathlength)]=i;
        bf(path,n,i+1,k,pathlength,ans,returnSize);
        (*pathlength)--;//回溯 步骤!!
    }
}

int** combine(int n, int k, int* returnSize, int** returnColumnSizes) {
    int **ans=(int **)malloc(sizeof(int *)*200001);
    *returnSize=-1;
    int pathlength=-1;//考虑路径,用到path,pathlength
    int *path=(int *)malloc(sizeof(int )*k);
    bf(path,n,1, k, &pathlength,ans,returnSize);//returnsize不需要&

    (*returnSize)++;//returnsize指向数组的实际大小

    

    *returnColumnSizes=(int*)malloc(sizeof(int )*(*returnSize));//column的意义
    for(int i=0;i<(*returnSize);i++){
        (*returnColumnSizes)[i]=k;
    }
    
    return ans;
}

216.组合总和III

力扣题目链接(opens new window)

找出所有相加之和为 n 的 k 个数的组合。组合中只允许含有 1 - 9 的正整数,并且每种组合中不存在重复的数字。

说明:

  • 所有数字都是正整数。
  • 解集不能包含重复的组合。

示例 1: 输入: k = 3, n = 7 输出: [[1,2,4]]

示例 2: 输入: k = 3, n = 9 输出: [[1,2,6], [1,3,5], [2,3,4]

void bp(int **ans,int *size,int *path,int *p,int k,int n,int start,int sum){
    if(sum>n) return;//剪枝
    if(sum==n && *p==k){
        ans[*size]=(int *)malloc(sizeof(int)*k);
        for (int i=0;i<k;i++){
            ans[*size][i]=path[i];
        }
        (*size)++;
        return;//不要忘记写return
    }
    else if(*p==k){//另外一种终止情况
        return;
    }
    for(int i=start;i<=9;i++){
        path[(*p)++]=i;
        bp(ans, size, path, p,  k,  n, i+1,  sum+i);//i+1,而不是start+1
        (*p)--;
    }
}


int** combinationSum3(int k, int n, int* returnSize, int** returnColumnSizes) {
    int **ans=(int **)malloc(sizeof(int *)*500);
    int size=0;
    
    int *path=(int *)malloc(sizeof(int)*k);
    int p=0;

    bp(ans, &size,path, &p, k, n, 1, 0);

    *returnSize=size;
    *returnColumnSizes=(int *)malloc(sizeof(int)*(size));
    for (int i=0;i<size;i++){
        (*returnColumnSizes)[i]=k;//要加括号
    }
    return ans;

}

17.电话号码的字母组合

力扣题目链接(opens new window)

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。

给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

char phoneMap[11][5] = {"\0", "\0", "abc\0", "def\0", "ghi\0", "jkl\0", "mno\0", "pqrs\0", "tuv\0", "wxyz\0"};

void bp(char**ans,int *size,char *path,int *p,int len,char* digits,int d){
    if(*p==len){
        ans[*size] =(char*)malloc(sizeof(char)*(len+1));
        for(int i=0;i<len;i++){
            ans[*size][i]=path[i];
            printf("%c",path[i]);
        }        
        ans[*size][len]='\0';

        printf("\n");
        (*size)++;
        return;
    }

    int number= digits[d]-'0';
    char * nowd=phoneMap[number];
    int dlen=strlen(nowd);

    for(int i=0;i<dlen;i++){
        char new=nowd[i];
        path[(*p)++]=new;
        bp(ans, size, path,p, len, digits,d+1);
        (*p)--;
    }


}

char** letterCombinations(char* digits, int* returnSize) {
    int len=strlen(digits);
    char**ans=(char**)malloc(sizeof(char*)*pow(4,len));
    int size=0;

    if (len==0) {
        *returnSize=0;
        return ans;
    }

    char *path=(char*)malloc(sizeof(char)*(len+1));
    int p=0;

    bp(ans,&size, path, &p, len, digits, 0);

    *returnSize=size;

    return ans;


}

标签:malloc,22,int,个数,随想录,char,算法,ans,path
From: https://blog.csdn.net/weixin_65180740/article/details/140663418

相关文章

  • 代码随想录算法训练营第24天:回溯03:93.复原IP地址;78.子集;90.子集II
    93.复原IP地址力扣题目链接(opensnewwindow)给定一个只包含数字的字符串,复原它并返回所有可能的IP地址格式。有效的IP地址正好由四个整数(每个整数位于0到255之间组成,且不能含有前导0),整数之间用'.'分隔。例如:"0.1.2.201"和"192.168.1.1"是有效的IP地址,......
  • 代码随想录算法训练营第九天 | 151.翻转字符串里的单词,卡码网:55.右旋转字符串,28. 实现
    151.翻转字符串里的单词题目链接:力扣题目链接文章讲解:代码随想录 视频讲解:字符串复杂操作拿捏了!|LeetCode:151.翻转字符串里的单词思路这道题目可以说是综合考察了字符串的多种操作。其实这道题和反转字符串这道题目很像,而且用法也是通用的方法一:切片,reverse,以及......
  • 代码随想录算法训练营第十天 | 232.用栈实现队列 , 225. 用队列实现栈 , 20. 有效的括号
    前两道题目之前单独写了文章,此处就不再重复。232.用栈实现队列-CSDN博客225.用队列实现栈-CSDN博客20.有效的括号题目链接:力扣题目链接文章讲解:代码随想录 视频讲解:栈的拿手好戏!|LeetCode:20.有效的括号思路括号匹配是使用栈解决的经典问题。由于栈结构的......
  • 2024“钉耙编程”中国大学生算法设计超级联赛(3)复盘总结
    2024“钉耙编程”中国大学生算法设计超级联赛(3)本场我其实并没有给团队贡献是任何一个AC,连最简单的题都因为题目读错没有写出来。纯纯抱大佬大腿,然后赛后被嘲讽深度自同构-limie首先,先考虑对于一个有\(n\)个节点的树应该怎么做。设\(f_i\)表示\(i\)个节点的树中有多少个......
  • 科普文:常见的分布式协议与算法
    主要列举一致性Hash算法、Gossip协议、QuorumNWR算法、PBFT算法、PoW算法、ZAB协议,Paxos会分开单独讲。科普文:搞懂ApacheBookKeeper和一致性协议-CSDN博客科普文:分布式系统中的一致性协议概叙-CSDN博客一致性Hash算法#一致性Hash算法是为了解决Hash算法的迁移成本,以一个1......
  • FP-growth算法药品货位优化系统操作手册V1.0
    未经授权严禁商用,科研合作请联系作者。Email:[email protected]作者:辛昊,青岛大学附属青岛市第三人民医院药学部指导老师:曹建华,青岛大学附属青岛市第三人民医院药学部李春凯,青岛大学附属青岛市第三人民医院药学部思路及创意来源:王丰,西安交通大学医学院第一附属医院药学部......
  • 算法:效率度量方法与函数渐进增长
    度量方法与函数渐进增长算法效率的度量方法1.时间复杂度(TimeComplexity):常见时间复杂度及其比喻:2.空间复杂度(SpaceComplexity):渐进增长常见渐进增长函数及其比喻:实例分析算法效率的度量方法1.时间复杂度(TimeComplexity):定义:时间复杂度表示算法执行所需时间相......
  • 文心一言 VS 讯飞星火 VS chatgpt (311)-- 算法导论22.2 9题
    九、设G=(V,E)......
  • 代码随想录 day 37 完全背包 | 零钱兑换 II | 组合总和 Ⅳ | 爬楼梯 (进阶)
    完全背包完全背包解题思路由于我们可以重复放入物体,那么在遍历背包重量时就必须从前往后遍历,因为这样就可以重复放入了,其余的部分和01背包相同知识点完全背包心得学会了如何解决纯完全背白零钱兑换II零钱兑换II解题思路和之前01背包求总数的思路相同,唯一的不同点在......
  • 基础篇之如何了解一个算法,从这些方面来探索-以ssd为例
    以SSD(SingleShotMultiBoxDetector)算法为例,你可以从多个方面了解它的基础知识、结构、工作原理、优点以及应用。以下是一些建议的问题和学习路径:基础介绍SSD算法的基本概念是什么?你可以问:SSD是什么?它解决了什么问题?SSD算法的优点和缺点有哪些?你可以问:SSD相对于......