更新:
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;
}