题目:Letter Combinations of a Phone Number

将电话号码的组合转换称所有可能的字母组合。

思路:

首先将电话键盘中的0->9的数字对应的字母集合放到一个常量二维数组中便于搜索。

[

  [' ']//0

  []//1

  ['a','b','c']//2

  ...

  ['w','x','y','z']//9

]

然后递归搜索每一位给定的数字对应的字母数组,一一组合。

得到返回后将其与当前数字的字母数组组合得到新的数组在返回。

  1 /***************************************************************************************************
  2 Given a digit string, return all possible letter combinations that the number could represent.
  3 A mapping of digit to letters (just like on the telephone buttons) is given below.
  4 1(0_0)    2(abc)    3(def)
  5 4(ghi)    5(jkl)    6(mno)
  6 7(pqrs)    8(tuv)    9(wxyz)
  7                 0( )
  8 Input:Digit string "23"
  9 Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].
 10 Note:
 11 Although the above answer is in lexicographical order, your answer could be in any order you want.
 12 ***************************************************************************************************/
 13 #include<stdio.h>
 14 #include<stdlib.h>
 15 
 16 char **numToString(char **letters,int *retSize,int *lengths,char *digits,int pos){
 17     int i,num = digits[pos] - '0';
 18     if(pos == 0){//递归是反着的,当到第一个数字时开始返回
 19         char **s = (char **)malloc(lengths[num]*sizeof(char *));
 20         for(i = 0;i < lengths[num];i++){
 21             s[i] = (char *)malloc(2*sizeof(char));
 22             s[i][0] = letters[num][i];
 23             s[i][1] = '\0';//注意数组单个赋值末尾需手动加'\0'
 24         }
 25         *retSize = lengths[num];
 26         return s;
 27     }
 28     int k = 0,subLen;
 29     char **subs = numToString(letters,&subLen,lengths,digits,pos - 1);
 30     char **rets = (char **)malloc(subLen*lengths[num]*sizeof(char *));
 31     for(i = 0;i < subLen;i++){
 32         for(int j = 0;j < lengths[num];j++){//在末尾加上当前数字对应的字母
 33             rets[k] = (char *)malloc((pos + 2)*sizeof(char));
 34             //memset(rets[k],0,(pos + 2)*sizeof(char));
 35             strncpy(rets[k],subs[i],pos);//复制前面的转换结果,一个要复制当前数字对应的字母的数量的次数
 36             rets[k][pos] = letters[num][j];
 37             rets[k][pos + 1] = '\0';
 38             k++;
 39         }
 40         free(subs[i]);
 41         subs[i] = NULL;
 42     }
 43     free(subs);
 44 
 45     *retSize = k;
 46     return rets;
 47 }
 48 
 49 /**
 50  * Return an array of size *returnSize.
 51  * Note: The returned array must be malloced, assume caller calls free().
 52  */
 53 char** letterCombinations(char* digits, int* returnSize) {
 54         if(digits == NULL || strlen(digits) < 1){
 55             *returnSize = 0;
 56             return NULL;
 57         }
 58     int i;
 59     int lengths[] = {1,0,3,3,3,3,3,4,3,4};
 60     char **letters = (char **)malloc(10*sizeof(char *));
 61     letters[0] = (char*)malloc(sizeof(char));
 62     letters[0][0] = ' ';
 63     letters[1] = NULL;
 64     letters[2] = (char*)malloc(4*sizeof(char));
 65     letters[2][0] = 'a';letters[2][1] = 'b';letters[2][2] = 'c';letters[2][3] = '\0';
 66     letters[3] = (char*)malloc(4*sizeof(char));
 67     letters[3][0] = 'd';letters[3][1] = 'e';letters[3][2] = 'f';letters[3][3] = '\0';
 68     letters[4] = (char*)malloc(4*sizeof(char));
 69     letters[4][0] = 'g';letters[4][1] = 'h';letters[4][2] = 'i';letters[4][3] = '\0';
 70     letters[5] = (char*)malloc(4*sizeof(char));
 71     letters[5][0] = 'j';letters[5][1] = 'k';letters[5][2] = 'l';letters[5][3] = '\0';
 72     letters[6] = (char*)malloc(4*sizeof(char));
 73     letters[6][0] = 'm';letters[6][1] = 'n';letters[6][2] = 'o';letters[6][3] = '\0';
 74     letters[7] = (char*)malloc(5*sizeof(char));
 75     letters[7][0] = 'p';letters[7][1] = 'q';letters[7][2] = 'r';letters[7][3] = 's';letters[7][4] = '\0';
 76     letters[8] = (char*)malloc(4*sizeof(char));
 77     letters[8][0] = 't';letters[8][1] = 'u';letters[8][2] = 'v';letters[8][3] = '\0';
 78     letters[9] = (char*)malloc(5*sizeof(char));
 79     letters[9][0] = 'w';letters[9][1] = 'x';letters[9][2] = 'y';letters[9][3] = 'z';letters[9][4] = '\0';
 80 
 81     char **ss = numToString(letters,returnSize,lengths,digits,strlen(digits) - 1);
 82 
 83     for(int i = 0;i < 10;i++){
 84         free(letters[i]);
 85         letters[i] = NULL;
 86     }
 87     free(letters);
 88 
 89     return ss;
 90 }
 91 
 92 void main(){
 93     char digits[] = "32";//会自动加'\0'
 94     int size = 0;
 95     char **retstr = letterCombinations(digits,&size);
 96     for(int i = 0;i < size;i++){
 97         printf("%s\n",retstr[i]);
 98         free(retstr[i]);
 99     }
100     free(retstr);
101 }