-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path0211-Design_Add_and_Search_Words_Data_Structure.cpp
More file actions
144 lines (133 loc) · 3.71 KB
/
0211-Design_Add_and_Search_Words_Data_Structure.cpp
File metadata and controls
144 lines (133 loc) · 3.71 KB
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/*******************************************************************************
* 0211-Design_Add_and_Search_Words_Data_Structure.cpp
* Billy.Ljm
* 19 Mar 2023
*
* =======
* Problem
* =======
* https://leetcode.com/problems/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.
*
* ===========
* My Approach
* ===========
* We'll us a Trie/prefix tree to store the remembered words. When looking up a
* widlcard, we simply iteratively check all the children of the Trie node.
*
* This will have a time complexity of O(n) for adding a word and O(n k) for
* searching for a word. It will also have a space complexity of O(n k), where n
* is the length of the word and k is the number of remembered words.
******************************************************************************/
#include <iostream>
#include <string>
#include <map>
/**
* n-ary tree node
*/
struct node {
std::map<char, node*> children; // children of node
bool end; // true if node is end of word, false otherwise
node() : end(false) {} // constructor
};
/**
* word dictionary implemented as Trie/prefix tree
*/
class WordDictionary {
public:
node* root; // root of prefix tree
WordDictionary() {
root = new node;
}
/**
* Add a word into the WordDictionary
*
* @param word word to be added
*/
void addWord(std::string word) {
node* crawler = root;
for (char c : word) {
if (crawler->children[c] == NULL) {
crawler->children[c] = new node;
}
crawler = crawler->children[c];
}
crawler->end = true;
}
/**
* Search if the word is in the WordDictionary
*
* @param word word to be searched
*/
bool search(std::string word) {
return recurse(word, 0, root);
}
/**
* deletes the WordDictionary
*/
void deleteDict() {
deleteNode(root);
}
private:
/**
* Deletes a node and all its children
*/
void deleteNode(node* nodee) {
for (const auto& child : nodee->children) {
deleteNode(child.second);
}
}
/**
* Recursively search for string w/ wildcard char in prefix tree
*
* @param word word to search for
* @param index index that has been searched up to
* @param crawler current node in prefix tree
*
* @return true if word is found, false otherwise
*/
bool recurse(std::string& word, size_t index, node* crawler) {
if (crawler == nullptr) {
return false;
}
else if (index == word.size()) {
return crawler->end;
}
else if (word[index] == '.') {
for (const auto& child : crawler->children) {
if (recurse(word, index + 1, child.second)) {
return true;
}
}
return false;
}
else {
if (crawler->children[word[index]] == NULL) {
return false;
}
else {
return recurse(word, index + 1, crawler->children[word[index]]);
}
}
}
};
int main(void) {
WordDictionary wordDictionary = WordDictionary();
wordDictionary.addWord("bad");
wordDictionary.addWord("dad");
wordDictionary.addWord("mad");
std::cout << std::boolalpha << wordDictionary.search("pad") << std::endl; // return False
std::cout << std::boolalpha << wordDictionary.search("bad") << std::endl; // return True
std::cout << std::boolalpha << wordDictionary.search(".ad") << std::endl; // return True
std::cout << std::boolalpha << wordDictionary.search("b..") << std::endl; // return True
return 0;
}