leetcode 17. 电话号码的字母组合

题目描述

https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number/

思路整理

看到这个题,想法的算法就是枚举,枚举的实现也有也有多种方式。可以采用循环,也可以采用递归。
但是这道题首先要解决的是内存的问题,如何“一次性”申请一个合适大小的内存。因为C语言不具备动态申请内存的条件。如果采用C++ vector,多次创建string对象+容器操作,内存的复杂度会减小一点。本题可以考虑优先构建号码簿二维数组,再基于输入的数字串计算出存储结果的二维数组的大小。
其次要解决的问题,就是如果循环的问题,大体思路还是先循环输入的字符串,对每一个数字所对应全部字母按树形结构轮询。
方案一:看到树形结构,通常会优先考虑采用递归的方式。
方案二:将该问题转化为一个二维数组填值的问题,通过处理行和列的序列关系,分别对二维数组按行填值,这样可以避免递归,直接用两个for循环解决。
方案1是我想的,给出代码,方案二是别人想的,我给出链接。

代码show

#include 
#include 
#include 

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.确定遍历得到数组值的方法。

你可能感兴趣的:(leetcode 17. 电话号码的字母组合)