提交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; }