题目描述
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
示例:
输入:“23”
输出:[“ad”, “ae”, “af”, “bd”, “be”, “bf”, “cd”, “ce”, “cf”].
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
递归代码
执行用时 :
0 ms
, 在所有 c 提交中击败了
100.00%
的用户
内存消耗 :
7.1 MB
, 在所有 c 提交中击败了
41.67%
的用户
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
//套路,套用框架
void backTrack(char ** return_list ,char * digits ,int i,int digits_size,char *model,int* ji)
{
if(digits_size>i)
{
char task='a';//用于指示按键中字母
if(digits[i]<'7')
{
task+=(int)(digits[i]-'2')*3;//采用ascll码来计算字母
for(int p=0;p<3;p++)//分别将按键中的几个字母放入数组
{
char task1 =task+p;
model[i]=task1;
backTrack(return_list,digits,i+1,digits_size,model,ji);//递归求下一个数字的字母
}
}
if(digits[i]=='7')//由于7,9,8按键中字母不同所以分别处理
{
task='p';
for(int p=0;p<4;p++)
{
char task1 =task+p;
model[i]=task1;
backTrack(return_list,digits,i+1,digits_size,model,ji);
}}
if(digits[i]=='8')
{
task=(int)(digits[i]-'2')*3+task+1;
for(int p=0;p<3;p++)
{
char task1 =task+p;
model[i]=task1;
backTrack(return_list,digits,i+1,digits_size,model,ji);
}
}
if(digits[i]=='9')
{
task='w';
for(int p=0;p<4;p++)
{
char task1 =task+p;
model[i]=task1;
backTrack(return_list,digits,i+1,digits_size,model,ji);
}
}
}
else{//这是递归到底层的标志和处理,得到一个字符串放到二维目标数组中
return_list[(*ji)]=(char*)calloc(digits_size+1,sizeof(char));
strcpy( return_list[(*ji)],model);
return_list[(*ji)][digits_size]='\0';
(*ji)++;
return;
}
}
char ** letterCombinations(char * digits, int* returnSize){
//类似n皇后问题采用
int k=1;//计数用
int ji =0;
(*returnSize) = 0;
if(strlen(digits) == 0)
{
return NULL;
}
for(int i = 0; i < strlen(digits); i++)//这一步是为了提前计算目标二维数组的元素多少
{
int m=(int)(digits[i]-'0');
if(m==7||m==9) m=4;
else m=3;
k=k* m;
}
char **res = (char**)malloc(k*sizeof(char*));
char *result = (char*)calloc(strlen(digits) + 1,sizeof(char));
backTrack(res,digits,0,strlen(digits),result,returnSize);
return res;
}
非递归非回溯代码
这是题解区中看到的代码块,供大家参考
char ** letterCombinations(char * digits, int* returnSize){
*returnSize = 0;
char **char_ret = NULL;
if(digits == NULL || digits[0] == '\0')
return char_ret;
char *map1[8] = {"abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
int map_long[8] = {3,3,3,3,3,4,3,4};
int digits_len = strlen(digits);
int i = 0, j = 0, k = 0, l = 0;
int num_char = 0;
int cur_level = 1;
while(i < digits_len)
cur_level *= map_long[digits[i++] - '2'];
num_char = *returnSize = cur_level;
i = 0;
char_ret = (char **)malloc(sizeof(char **) * num_char);
while(i < cur_level){
char_ret[i] = (char *)malloc(sizeof(char) * digits_len + 1);
memset(char_ret[i],0,sizeof(char) * digits_len + 1);
i++;
}
i = 0;
//将输入的数字对应的字母按排输入
//遍历每个输入的字母
while(i < digits_len){
//第i个输入的字符代表的字母是map1[digits[i] - '2']
//当遍历到的数字字符只映射3个字母,那么即每个字母在这一行要写(*returnSize)/3次..
if(digits[i] == '7' || digits[i] == '9')
cur_level = cur_level / 4;
else
cur_level = cur_level / 3;
//写入的总数是num_char个
while(j < num_char){
//每个字母需要些多少次
while(k < cur_level){
char_ret[j+k][i] = map1[digits[i] - '2'][l];
k++;
}
if(l < map_long[digits[i] - '2'] - 1)
l++;
else
l = 0;
j = j + k;
k = 0;
}
l = 0;
j = 0;
i++;
}
return char_ret;
}
作者:wjf1993
链接:https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number/solution/cyu-yan-an-xing-xie-ru-by-wjf1993/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。