题目描述
https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number/
思路整理
看到这个题,想法的算法就是枚举,枚举的实现也有也有多种方式。可以采用循环,也可以采用递归。
但是这道题首先要解决的是内存的问题,如何“一次性”申请一个合适大小的内存。因为C语言不具备动态申请内存的条件。如果采用C++ vector,多次创建string对象+容器操作,内存的复杂度会减小一点。本题可以考虑优先构建号码簿二维数组,再基于输入的数字串计算出存储结果的二维数组的大小。
其次要解决的问题,就是如果循环的问题,大体思路还是先循环输入的字符串,对每一个数字所对应全部字母按树形结构轮询。
方案一:看到树形结构,通常会优先考虑采用递归的方式。
方案二:将该问题转化为一个二维数组填值的问题,通过处理行和列的序列关系,分别对二维数组按行填值,这样可以避免递归,直接用两个for循环解决。
方案1是我想的,给出代码,方案二是别人想的,我给出链接。
代码show
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *letter_matrix[10];
int letter_length[10];
void gettable(char **letters,int *letters_index,char *digits,int offset,char *record,int record_offset)
{
int i = 0;
int loop = 0;
if(digits[offset] == 0)
{
memcpy(letters[*letters_index],record,record_offset);
*letters_index = *letters_index + 1;
return;
}
int index = digits[offset] - '0';
if (letter_length[index] > 0) {
loop = letter_length[index];
}
for(i = 0;i < loop;i++)
{
record[record_offset] = letter_matrix[index][i];
gettable(letters,letters_index,digits, offset + 1, record, record_offset + 1);
}
}
/**
** Return an array of size *r eturnSize.
** Note: The returned array must be malloced, assume caller calls free().
**/
static char** letterCombinations(char* digits, int* returnSize)
{
letter_matrix[0] = "";
letter_matrix[1] = " ";
letter_matrix[2] = "abc";
letter_matrix[3] = "def";
letter_matrix[4] = "ghi";
letter_matrix[5] = "jkl";
letter_matrix[6] = "mno";
letter_matrix[7] = "pqrs";
letter_matrix[8] = "tuv";
letter_matrix[9] = "wxyz";
letter_length[0] = 0;
letter_length[1] = 1;
letter_length[2] = 3;
letter_length[3] = 3;
letter_length[4] = 3;
letter_length[5] = 3;
letter_length[6] = 3;
letter_length[7] = 4;
letter_length[8] = 3;
letter_length[9] = 4;
int i, j, k;
int empty = 1;
int count = 1;
int digit_len = strlen(digits);
for (i = 0; i < digit_len; i++) {
int index = digits[i] - '0';
if (letter_length[index] > 0) {
empty = 0;
count *= letter_length[index];
}
}
if (empty) {
*returnSize = 0;
return NULL;
}
*returnSize = count;
char **letters = malloc(sizeof(char *) * count);
for (i = 0; i < count; i++) {
letters[i] = malloc(digit_len + 1);
memset(letters[i], 0, digit_len + 1);
}
char record[10] = {0};
int letters_index=0;
gettable(letters,&letters_index,digits,0,record,0);
return letters;
}
int main(int argc, char **argv) {
int i, size = 0;
char test[10] = "249";
char ** letters = letterCombinations(test, &size);
for (i = 0; i < size; i++) {
printf("%s\n", letters[i]);
free(letters[i]);
}
free(letters);
return 0;
}
方案二:
https://github.com/crazy-shawn-liu/leetcode/tree/master/051_n_queens
总结
1.确定初始二维数组的大小及布局。
2.确定遍历得到数组值的方法。