给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母
针对此题涉及到的两种算法进行debug解析:
方法一:回溯算法
Debug工具:QT
注意事项:strcpy本身的代码缺陷
源码:
//用数组表示对应的字符
char two_les[4] = { 'a', 'b', 'c', '\0'};
char thr_les[4] = { 'd', 'e', 'f', '\0' };
char fou_les[4] = { 'g', 'h', 'i', '\0' };
char fif_les[4] = { 'j', 'k', 'l', '\0' };
char six_les[4] = { 'm', 'n', 'o', '\0' };
char sev_les[5] = { 'p', 'q', 'r', 's', '\0' };
char eig_les[4] = { 't', 'u', 'v', '\0' };
char nin_les[5] = { 'w', 'x', 'y', 'z', '\0' };
//数组指针进行二次封装,这样二维数组就分成了行和列
char* ALL[8] = { two_les, thr_les, fou_les, fif_les, six_les, sev_les, eig_les, nin_les };
/*Result:存储所有字符组合后的字符串*/
/*Result_Index:一维索引,递增写入字符串*/
/*Path:单个字符串*/
/*Path_Index:二维索引,递增读取字符*/
/*digits:输入的字符串*/
/*Start_Index:输入的字符串索引*/
/*len:是一个固定长度的值,在我们确定digits的时候这个值就已经确定了*/
void Back_Track(char** Result, int* Result_Index, char* Path, int* Path_Index, char* digits, int Start_Index, int len) {
/*Start_Index == len 这个判断条件作为边界判断,此时已经达到最大最长字符串,此时会在字符串末尾加上结束字符,赋值操作后Result中的索引会加1;*/
if (Start_Index == len) {
Path[*Path_Index] = '\0';
char* temc = (char*)malloc(sizeof(char) * (len + 1));
strcpy(temc, Path);
Result[*Result_Index] = temc;
(*Result_Index)++;
return;
}
/*未达到边界值的计算,Back_Track函数在第一次递归的时候会因为Start_Index + 1拿到下一个字符串的指针,并且深度优先;当达到最底层的时候从底层执行for循环然后慢慢往上退出;Path_Index的++和--保证指针指向的是当前索引,从而配合for循环取值*/
char* Target = ALL[digits[Start_Index] - '0' - 2];
int tar_len = strlen(Target);
for (int i = 0; i < tar_len; i++) {
Path[*Path_Index] = Target[i];
(*Path_Index)++;
Back_Track(Result, Result_Index, Path, Path_Index, digits, Start_Index + 1, len);
(*Path_Index)--;
}
}
char* Result[144];//由于最多只有四个字母,所以其中的最大可能情况为3*3*4*4=144;
char Path[5];//由于最多只有四个字母,加上结束符,则其最大可能使用量为5;
char** letterCombinations(char* digits, int* returnSize) {
*returnSize = 0;
int len = strlen(digits);
if(len == 0){
return NULL;
}//有一个空示例,不能返回一个含有一个空字符串的字符串数组而是返回一个字符串数组空指针,所以需要单独写出。
int Path_Index = 0;
Back_Track(Result, returnSize, Path, &Path_Index, digits, 0, len);
return Result;
}