• LeetCode //C - 211. Design Add and Search Words Data Structure


    211. Design Add and Search Words Data Structure

    Design a data structure that supports adding new words and finding if a string matches any previously added string.

    Implement the WordDictionary class:

    • WordDictionary() Initializes the object.
    • void addWord(word) Adds word to the data structure, it can be matched later.
    • bool search(word) Returns true if there is any string in the data structure that matches word or false otherwise. word may contain dots ‘.’ where dots can be matched with any letter.
       
    Example:

    Input:
    [“WordDictionary”,“addWord”,“addWord”,“addWord”,“search”,“search”,“search”,“search”]
    [[],[“bad”],[“dad”],[“mad”],[“pad”],[“bad”],[“.ad”],[“b…”]]
    Output:
    [null,null,null,null,false,true,true,true]
    Explanation:
    WordDictionary wordDictionary = new WordDictionary();
    wordDictionary.addWord(“bad”);
    wordDictionary.addWord(“dad”);
    wordDictionary.addWord(“mad”);
    wordDictionary.search(“pad”); // return False
    wordDictionary.search(“bad”); // return True
    wordDictionary.search(“.ad”); // return True
    wordDictionary.search(“b…”); // return True

    Constraints:
    • 1 <= word.length <= 25
    • word in addWord consists of lowercase English letters.
    • word in search consist of ‘.’ or lowercase English letters.
    • There will be at most 2 dots in word for search queries.
    • At most 1 0 4 10^4 104 calls will be made to addWord and search.

    From: LeetCode
    Link: 211. Design Add and Search Words Data Structure


    Solution:

    Ideas:

    1. TrieNode Structure:
    Each node in the Trie is represented by a TrieNode structure. It has the following components:

    • An array of pointers, children, where each pointer corresponds to a letter in the English alphabet (26 lowercase letters).
    • A boolean flag, isEndOfWord, to signify whether a word ends at this node.

    2. WordDictionary Structure:
    The WordDictionary itself is represented by a structure, which holds a pointer to the root node of the Trie.

    3. wordDictionaryCreate:
    This function initializes the WordDictionary object and allocates memory for the root node of the Trie.

    4. wordDictionaryAddWord:
    This function is used to insert words into the Trie. For each character in the word, it traverses down the Trie, creating new nodes if needed, until the end of the word is reached, at which point it sets the isEndOfWord flag to true.

    5. wordDictionarySearch and searchHelper:

    • The wordDictionarySearch function is used to search for a word in the Trie, with support for the . character, which can match any letter.
    • It calls a helper function searchHelper, which performs a recursive search to handle the . character.
    • If the searchHelper encounters a . character, it recursively checks all its children.
    • If it can traverse the entire word and reach a node where isEndOfWord is true, it returns true; otherwise, it returns false.

    6. wordDictionaryFree and freeNode:

    • These functions deallocate the memory used by the WordDictionary and its nodes.
    • freeNode is a recursive function that frees all the child nodes before freeing the parent node.
    Code:
    #define ALPHABET_SIZE 26
    
    typedef struct TrieNode {
        struct TrieNode *children[ALPHABET_SIZE];
        bool isEndOfWord;
    } TrieNode;
    
    typedef struct {
        TrieNode *root;
    } WordDictionary;
    
    TrieNode* createNode() {
        TrieNode *newNode = (TrieNode *)calloc(1, sizeof(TrieNode));
        return newNode;
    }
    
    WordDictionary* wordDictionaryCreate() {
        WordDictionary *dict = (WordDictionary *)malloc(sizeof(WordDictionary));
        dict->root = createNode();
        return dict;
    }
    
    void wordDictionaryAddWord(WordDictionary* obj, char * word) {
        TrieNode *node = obj->root;
        for (int i = 0; word[i] != '\0'; i++) {
            int index = word[i] - 'a';
            if (!node->children[index])
                node->children[index] = createNode();
            node = node->children[index];
        }
        node->isEndOfWord = true;
    }
    
    bool searchHelper(TrieNode *node, char *word) {
        for (int i = 0; word[i] != '\0'; i++) {
            if (word[i] == '.') {
                for (int j = 0; j < ALPHABET_SIZE; j++) {
                    if (node->children[j] && searchHelper(node->children[j], word + i + 1))
                        return true;
                }
                return false;
            } else {
                int index = word[i] - 'a';
                if (!node->children[index])
                    return false;
                node = node->children[index];
            }
        }
        return node->isEndOfWord;
    }
    
    bool wordDictionarySearch(WordDictionary* obj, char * word) {
        return searchHelper(obj->root, word);
    }
    
    void freeNode(TrieNode *node) {
        for(int i = 0; i < ALPHABET_SIZE; i++)
            if(node->children[i])
                freeNode(node->children[i]);
        free(node);
    }
    
    void wordDictionaryFree(WordDictionary* obj) {
        if(!obj) return;
        freeNode(obj->root);
        free(obj);
    }
    
    /**
     * Your WordDictionary struct will be instantiated and called as such:
     * WordDictionary* obj = wordDictionaryCreate();
     * wordDictionaryAddWord(obj, word);
     
     * bool param_2 = wordDictionarySearch(obj, word);
     
     * wordDictionaryFree(obj);
    */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
  • 相关阅读:
    画一个有6个顶点的赋权有向图
    AnyDrop 一款自部署的内容共享工具
    nginx解决静态页面中ajax跨域方案配置
    麒麟V10服务器搭建FTP服务
    【安全狗高危安全通告】GitLab远程代码执行漏洞
    【Unity实战】手戳一个自定义角色换装系统——2d3d通用
    测试流程||接口测试
    Pytorch 基于ResNet-18的服饰识别(使用Fashion-MNIST数据集)
    ChatGPT高级数据分析功能
    Git 常用指令
  • 原文地址:https://blog.csdn.net/navicheung/article/details/133375469