Leetcode第17题电话号码的数字组合|C语言

更新:
letterMap是下标对应的字符串,即:
{
下标0:“0”
下标1:“0”
下标2:“abc”
下标3:“def”
下标4:“ghi”
下标5:“jkl”
下标6:“mno”
下标7:“pqrs”
下标8:“tuv”
下标9:“wxyz”
}
digits是题目给的字符数组,digits[某一位]-'0’表示字符数组对应的数字

大致思路,如果是电脑端的话,另外打开代码的窗口跟着走一遍就更好了:
举个题目中的例子,digits为“23”
1.当top小于digits的长度时,先取出digits第一位对应的数字,因为digits中各元素都是char类型,所以需要减‘0’,才是数字,再在letterMap中取出对应的字符串。比如digits数组第一个元素是‘2’,因为是char类型,所以得用‘2’-‘0’,就得到int型数字,在取出letterMap[2]中的字符串“abc”,这样就得到了电话2号键对应的字符串。
2.因为以digits‘2’开头的字符祝贺可以以‘a’开头,可以以‘b’开头,也可以以‘c’开头,所以你需要用strlen(pWord)作为次数进行遍历,遍历中递归调用函数。因为digits中index=1的元素我们已经取出了,所以递归中我们需要将index+1。又因为stack[top]中我们通过遍历将其存为‘a’、‘b’或‘c’,在递归中我们需要探究下一位元素需要存什么字符,所以参数中top也需要加1。执行大概是这种树形结构:

 第一层           top=0                a                            b                             c
 第二层           top=1           d   e   f                   d   e   f                   d   e   f  

3.我们以第一条线路"ad"为例,执行到第二层时,此时top=1,将d加入stack[top],然后执行下一层递归。在这层递归中,top=2,满足if(top>=len)这一条件,即此时stack中的元素数量等于题目要求的每一组的元素个数,于是我们可以收割结果。在指针数组的第*returnSize(表示已经收割的结果数组数量,因为现在是第一个结果,所以值为0)个指针中创建一个比top大1(因为字符数组需要额外存放’\0’的空间)的数组空间,将“ad”存进去,并补上’\0’,*returnSIze指针,然后返回。
4.返回后我们又回到了第二层,这一层top=1,此次for循环已经执行完毕,所以进入下一层循环,即i=1,将‘e’赋给stack[top],即此时stack中的元素为“ae”,递归进行上述操作后返回,i=2,将‘f’赋给stack[top],递归进行上述操作后返回,然后由于i自增后等于3,不满足i<strlen(pWord)的条件,返回第一层,此时top=0。由于本次for循环执行完毕,所以i自增,将‘b’赋给stack[top],即此时stack中的元素为“b”,又进入第二层递归进行上述操作,不再赘述。
5.按例子走了几条线路,应该就比较清楚了。

分割线:---------------------
跟着大佬的答案敲了一下,懵懵懂懂,待更新

char *letterMap[]={"0","0","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};

void backTrack(char* digits,int *returnSize,char **returnStr,int index,char *stack,int top){
//index表示本层次遍历到digits的哪一位数,returnStr保存已经收割的字符数组
//stack表示单次字符组合,top表示stack中有多少字符,其他为题目给的参数
    int len=strlen(digits);
    if(top>=len){
        returnStr[*returnSize]=(char*)malloc(sizeof(char)*(top+1));
        memcpy(returnStr[(*returnSize)],stack,sizeof(char)*top);
        returnStr[(*returnSize)++][top]='\0';
        return;
    }
    else{
        char *pWord=letterMap[digits[index]-'0'];
        for(int i=0;i<strlen(pWord);i++){
            stack[top]=pWord[i];
            backTrack(digits,returnSize,returnStr,index+1,stack,top+1);
        }
    }
}

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
char ** letterCombinations(char * digits, int* returnSize){
    *returnSize=0;
    if(digits==NULL||strlen(digits)==0)
        return NULL;
    char **returnStr=(char**)malloc(sizeof(char*)*200);
    
    char* pWord=letterMap[digits[0]-'0'];
    int indexlen=strlen(pWord);
    char stack[4]={0};
    for(int i=0;i<indexlen;i++){
        stack[0]=pWord[i];
        backTrack(digits,returnSize,returnStr,1,stack,1);
    }
    return returnStr;
}

执行情况

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值