题目描述:
给定一个仅包含数字 2-9
的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
示例 1:
输入:digits = "23" 输出:["ad","ae","af","bd","be","bf","cd","ce","cf"]
示例 2:
输入:digits = "" 输出:[]
示例 3:
输入:digits = "2" 输出:["a","b","c"]
提示:
0 <= digits.length <= 4
digits[i]
是范围['2', '9']
的一个数字。
通过次数
755.5K
提交次数
1.3M
通过率
58.4%
题目分析:
一个图结构的典型的深度优先搜索问题(或者说是回溯问题)。我们用递归的方法来解决这个问题。先创建一个堆栈(这里直接用一个char型的数组来模拟)用来存放生成的字母组合,并且确定递归的层次n(即输入字符串的个数)。把digits和递归层次index传进递归函数里。
当递归到第n层(即index==n)时,堆栈里的前n个字符就是新生成的一种组合,赋给保存字母组合的数组中。然后退出递归。
当没有递归到第n层时,就遍历当前层次数字对应的所有字母,在遍历时,先将所遍历的字母压栈,压栈后进行下一层次的递归,递归结束后退栈,下一个字母入栈。
代码:
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
char *phone[]={"\0","\0","abc\0","def\0","ghi\0","jkl\0","mno\0","pqrs\0","tuv\0","wxyz\0"};
char **combinations;//组合
int combinations_size;//组合数
int digits_size;//数字个数,例如"23"的digits_size=2;
char *stack;
int top;
void dfs(char *digits,int index)
{
//到达最底层后就出现了一种组合
if(index==digits_size)
{
/*
char *temp=(char *)malloc(sizeof(char)*(digits_size+1));
for(int i=0;i<digits_size;i++) temp[i]=stack[i];
temp[digits_size]='\0';
combinations[combinations_size++]=temp;
return ;
*/
//为新出现的组合申请空间
combinations[combinations_size]=(char *)malloc(sizeof(char)*(digits_size+1));
//把堆栈中的新组合提取出来
for(int i=0;i<digits_size;i++)
combinations[combinations_size][i]=stack[i];
combinations[combinations_size][digits_size]='\0';//刚开始第一个[]没加上去,一直出错
combinations_size++;
return ;
}
int a=digits[index]-'0';//这一层的字符串对应的数字,例中"23"第零层对应的是2
for(int i=0;i<strlen(phone[a]);i++)
{
stack[top++]=phone[a][i];
dfs(digits,index+1);
top--;
}
}
char ** letterCombinations(char * digits, int* returnSize){
digits_size=strlen(digits);
int sum=1;//组合数
for(int i=0;i<digits_size;i++)
{
int a=digits[i]-'0';
sum*=strlen(phone[a]);
}
combinations=(char **)malloc(sizeof(char *)*(sum+1));//最多4*4*3*3==114种组合
stack=(char *)malloc(sizeof(char)*digits_size);
combinations_size=0;
top=0;
if(digits_size==0){
*returnSize=0;
return combinations;
}
dfs(digits,0);
*returnSize=combinations_size;
return combinations;
}