提交leetcode的时候遇到了问题,一直说访问越界,但仔仔细细检查n多遍,就是检查不出来。
由于我用到了count全局变量,自加一来代表当前数组访问的位置,
后来忽然想到,是否是在leetcode在运行测试用例的时候,是连续测试的,用的同一个上下文,这样的话,就没有对这个全局变量清零……
果真,清零以后就能够了……已经3:47了,这里先上代码,明天再详细说吧……html
今天更新一下这道题的思路。
能够先参考一下以前的两篇文章,按部就班,好理解一些:
leadcode的Hot100系列--78. 子集--位运算
leadcode的Hot100系列--78. 子集--回溯git
在 子集--回溯
的文章里面,介绍了一下数字的排列组合,用01来表示对应的数字是否存在。
若是咱们仍是按照这个思路,可是换一个想法呢?
0、1是否是自己就能够表明着字符串?
对应排列出来的000\001\010 ... 是否是就是至关于:
我须要一个数字组合,组合须要三位数,每一位的数字要么是0,要么是1。
这么一想,是否是就与题目一致了:
我须要一个字母组合,组合的位数就是输入的字符串长度,每一位的字母是对应的几个字母中的某一个。
对,就是这么想的,好比,输入“89”,就说明,字母组合的位数是两位,第一位字母是'tuv'里面的一个,第二位字母是'wxyz'里面的一个。
这里再看下以前上一篇中回溯的代码:数组
void backtrack (int t) { if (t == level) show(); else for (int i=0;i<=1;i++) { y[t]=i; backtrack(t+1); } }
重点来了!!!!测试
因此,当输入为“89”的时候,就能够生成这样一种树:
指针
控制了树的层数和树的分支(分支就是可选项)以后,就能够完成全部组合。code
char table[][5] = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"}; char level = 0; char *p[8]; // 指向数字对应的字符串,例如,当输入数字为"89"时,p[0]为"tuv",p[1]为"wxyz"。 char len[8]; // 对应上面p存储的字符串的长度,例如,当输入数字为"89"是,len[0]=3,len[1]=4。 char **out; //二维数组,是最终输出 int count = 0; // 用来记录当前已经生成了几个组合,对应着out数组的行坐标 char y[8] = {0}; // 记录每一次的组合结果 void backtrack(int level_now) { if (level_now == level) { memcpy(out[count], y, level); // 把此次组合结果拷贝到out数组中。这里为何须要用一个y数组来记录组合结果,而后拷贝到out中呢?你们能够本身想想 count ++; // 完成一个字符串 return; } for (int i=0; i<len[level_now]; i++) { y[level_now] = p[level_now][i]; backtrack(level_now+1); } return; } char ** letterCombinations(char * digits, int* returnSize){ level = strlen(digits); // 遍历的层数 *returnSize = 0; if (0 == level) return NULL; *returnSize = 1; for(int i=0; i<level; i++) { p[i] = table[digits[i]-'0']; // 对p数组进行赋值 len[i] = strlen(p[i]); if (len[i] == 0) { *returnSize = 0; return NULL; } *returnSize *= len[i]; // 计算总共有多少个组合 } out = (char **)calloc(*returnSize, sizeof(char *)); // 先分配行指针 if (NULL == out) return NULL; for (int i=0; i<*returnSize; i++) { out[i] = (char *)calloc(1, sizeof(char) * (level+1)); // 再分配每一个行指针的内容,由于字符串后面须要一个结束符'\0',因此这里须要level+1 if (NULL == out[i]) return NULL; } backtrack(0); count = 0; // 这里很重要!很重要!!很重要!!! return out; }