字符串专题之leetcode 208. 实现 Trie (前缀树)

题目:
实现一个 Trie (前缀树),包含 insert, search, 和 startsWith 这三个操作。

示例:
Trie trie = new Trie();

trie.insert(“apple”);
trie.search(“apple”); // 返回 true
trie.search(“app”); // 返回 false
trie.startsWith(“app”); // 返回 true
trie.insert(“app”);
trie.search(“app”); // 返回 true

说明:
你可以假设所有的输入都是由小写字母 a-z 构成的。
保证所有输入均为非空字符串。

解题思路:
维护一个结构体,通过结构体中的结构体数组指针相连接,每一个结构体连接条即为一个单词;
因为前缀树为字符串,故只需要申请26个字符长度即可。

#include <string.h>
#define NUM 26 

typedef struct {
    int isWord;
    struct Trie *nextList[NUM];
} Trie;

/** Initialize your data structure here. */

Trie* trieCreate() {
    //申请内存,并进行初始化
    Trie *root = (Trie *)calloc(1, sizeof(Trie));
    return root;
}

/** Inserts a word into the trie. */
void trieInsert(Trie* obj, char * word) 
{
    //将word中的每一个字符都放进去
    Trie *root = obj;
    int len = strlen(word);

    for (int i = 0; i < len; i++) {
        int id =  word[i] - 'a';
        //不存在则分配内存
        if (root ->nextList[id] == NULL) {
            root->nextList[id] = trieCreate();
        }
        //继续向下走
        root = root -> nextList[id];
    }
    root ->isWord = true;
}


/** Returns if the word is in the trie. */
bool trieSearch(Trie* obj, char * word) {
    Trie *root = obj;
    int len = strlen(word);

    for (int i = 0; i < len; i++) {
        int id = word[i] - 'a';
        if (root ->nextList[id] == NULL) {
            return false;
        }
        //继续向下走
        root = root -> nextList[id];
    }
    return root -> isWord;
}

/** Returns if there is any word in the trie that starts with the given prefix. */
bool trieStartsWith(Trie* obj, char * prefix) 
{
    Trie *root = obj;
    int len = strlen(prefix);

    for (int i = 0; i < len; i++) {
        int id = prefix[i] - 'a';
        if (root ->nextList[id] == NULL) {
            return false;
        }
        //继续向下走
        root = root -> nextList[id];
    }
    return true;
}

void trieFree(Trie* obj) 
{
    Trie *root = obj;
    for (int i = 0; i < NUM; i++) {
        if (root -> nextList[i] == NULL) {
            continue;
        }
        //递归释放,如果只释放单一节点,会造成该根节点下的子节点未释放,会造成内存泄露
        return trieFree(root -> nextList[i]);
    }
    free(root);
}

/**
 * Your Trie struct will be instantiated and called as such:
 * Trie* obj = trieCreate();
 * trieInsert(obj, word);
 
 * bool param_2 = trieSearch(obj, word);
 
 * bool param_3 = trieStartsWith(obj, prefix);
 
 * trieFree(obj);
*/
©️2020 CSDN 皮肤主题: 游动-白 设计师:上身试试 返回首页