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);
*/
相关推荐
wabs6663 小时前
关于图论【卡码网110.字符串迁移的思考】
数据结构·算法·图论
影视飓风TIM4 小时前
Linux下C程序编译:gcc 动态链接与静态链接全解
linux·c语言
hanlin034 小时前
刷题笔记:力扣第242、349题(哈希表)
笔记·算法·leetcode
aramae4 小时前
C++ IO流完全指南:从C标准库到C++流式编程
服务器·c语言·开发语言·c++·后端
only-qi5 小时前
大模型Agent面试攻略:落地工程痛点、评估体系与Agentic RAG核心精讲
人工智能·算法·面试·职场和发展·langchain·rag
麻瓜老宋6 小时前
AI开发C语言应用按步走,表达式计算器calc的第二十四步,结束开发,生成calc 用法指南
c语言·开发语言·atomcode
0x3F(小茶)7 小时前
STM32 SPI的5种方向模式
c语言·stm32·单片机·嵌入式硬件
Gauss松鼠会7 小时前
【GaussDB】GaussDB锁阻塞源头查询
java·开发语言·前端·数据库·算法·gaussdb·经验总结
oier_Asad.Chen7 小时前
【洛谷题解/AcWing题解】洛谷P4011 孤岛营救问题/AcWing1131拯救大兵瑞恩
数据结构·笔记·学习·算法·动态规划·图论·宽度优先
逻辑君7 小时前
基于 A2C 算法的双足机器人行走控制
人工智能·深度学习·算法·机器学习·机器人