LeetCode //C - 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:
c 复制代码
#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);
*/
相关推荐
We་ct几秒前
LeetCode 92. 反转链表II :题解与思路解析
前端·算法·leetcode·链表·typescript
载数而行5204 分钟前
数据结构系列15之图的存储方式2
c语言·数据结构·c++
春日见5 分钟前
如何查看我一共commit了多少个,是哪几个,如何回退到某一个版本
vscode·算法·docker·容器·自动驾驶
uesowys8 分钟前
华为OD算法开发指导-二级索引-Read and Write Path Different Version
java·算法·华为od
TracyCoder1238 分钟前
LeetCode Hot100(55/100)——347. 前 K 个高频元素
数据结构·算法·leetcode
IvanCodes10 分钟前
八、C语言构造类型
c语言·开发语言
码农三叔10 分钟前
(11-4-03)完整人形机器人的设计与实现案例:盲踩障碍物
人工智能·算法·机器人·人机交互·人形机器人
Wect15 分钟前
LeetCode 92. 反转链表II :题解与思路解析
前端·算法·typescript
Wect17 分钟前
LeetCode 138. 随机链表的复制:两种最优解法详解
前端·算法·typescript
近津薪荼18 分钟前
优选算法——前缀和(4):除了自身以外数组的乘积
算法