Skip to content

Commit 17451c3

Browse files
committed
add solution : 211. Design Add and Search Words Data Structure
1 parent 32fc22f commit 17451c3

File tree

1 file changed

+123
-0
lines changed
  • design-add-and-search-words-data-structure

1 file changed

+123
-0
lines changed
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
/**
2+
*@link https://leetcode.com/problems/design-add-and-search-words-data-structure/
3+
*
4+
* ์ ‘๊ทผ ๋ฐฉ๋ฒ• :
5+
* - set ํ™œ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•
6+
* - ๋‹จ์–ด ์ถ”๊ฐ€ํ•  ๋•Œ๋Š” set์— ์ €์žฅํ•˜๊ณ , ๋‹จ์–ด ์ฐพ์„ ๋•Œ๋งˆ๋‹ค cache๋ชฉ๋ก์—์„œ ๊ฐ’ ๊ฐ€์ ธ์˜ค๊ธฐ.
7+
* - ๋‹จ์–ด ์ถ”๊ฐ€ํ•˜๋ฉด ์ด์ „ ์บ์‹œ๋Š” ์‚ฌ์šฉํ•˜์ง€ ๋ชปํ•˜๋‹ˆ๊นŒ ํด๋ฆฌ์–ด ํ•ด์ฃผ๊ธฐ
8+
* - ์ด์ „ ๊ฐ’ ํ™œ์šฉํ•œ๋‹ค๋Š” ์žฅ์ ์ด ์žˆ์ง€๋งŒ ๋‹จ์–ด ์ถ”๊ฐ€์‹œ ๋‹ค์‹œ ์บ์‹œ ๋งŒ๋“ค์–ด์•ผํ•˜๋Š” ๋น„ํšจ์œจ ์กด์žฌ
9+
*
10+
* ์‹œ๊ฐ„๋ณต์žก๋„ : O(n * k)
11+
* - n์€ set์— ์ถ”๊ฐ€๋œ ๋‹จ์–ด ๊ธธ์ด, k๋Š” ๊ฐ ๋‹จ์–ด ํ‰๊ท  ๊ธธ์ด
12+
* - this.set ๋‹จ์–ด ์ˆœํšŒ => O(n)
13+
* - replaceAll, filter => O(k)
14+
*
15+
* ๊ณต๊ฐ„๋ณต์žก๋„ : O(n * k)
16+
* - n์€ ํŒจํ„ด์˜ ๊ฐœ์ˆ˜, k๋Š” ํŒจํ„ด์— ๋งค์นญ๋˜๋Š” ํ‰๊ท  ๋‹จ์–ด ์ˆ˜
17+
*/
18+
class WordDictionary {
19+
set: Set<string>;
20+
cache: Map<string, string[]>;
21+
constructor() {
22+
this.set = new Set();
23+
this.cache = new Map();
24+
}
25+
26+
addWord(word: string): void {
27+
this.set.add(word);
28+
// ์ƒˆ๋กœ์šด ๋‹จ์–ด๊ฐ€ ์ถ”๊ฐ€ ์‹œ ์บ์‹œ ํด๋ฆฌ์–ด
29+
this.cache.clear();
30+
}
31+
32+
search(word: string): boolean {
33+
// ์บ์‹œ์— ๊ฐ’์ด ์กด์žฌํ•˜๋ฉด ์ฆ‰์‹œ ๋ฆฌํ„ด
34+
if (this.cache.has(word)) return this.cache.get(word)!.length > 0;
35+
36+
// ์ •๊ทœํ‘œํ˜„์‹ ํŒจํ„ด ์ƒ์„ฑ
37+
const pattern = new RegExp(`^${word.replaceAll(".", "[a-z]")}$`);
38+
const matches = [...this.set].filter((item) => pattern.test(item));
39+
40+
// ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ ์บ์‹œ์— ์ €์žฅ
41+
this.cache.set(word, matches);
42+
43+
return matches.length > 0;
44+
}
45+
}
46+
47+
/**
48+
* Your WordDictionary object will be instantiated and called as such:
49+
* var obj = new WordDictionary()
50+
* obj.addWord(word)
51+
* var param_2 = obj.search(word)
52+
*/
53+
54+
// ์‹œ๊ฐ„ ๋ณต์žก๋„ ๊ฐœ์„ ํ•˜๊ธฐ ์œ„ํ•ด์„œ Trie ์ž๋ฃŒ ๊ตฌ์กฐ ์‚ฌ์šฉ
55+
class TrieNode {
56+
children: Map<string, TrieNode>;
57+
isEndOfWord: boolean;
58+
59+
constructor() {
60+
this.children = new Map();
61+
this.isEndOfWord = false;
62+
}
63+
}
64+
65+
/*
66+
* ์ ‘๊ทผ ๋ฐฉ๋ฒ• :
67+
* - ๊ฐ ๋ฌธ์ž ์ €์žฅํ•˜๊ณ  ๊ฒ€์ƒ‰ํ•˜๊ธฐ ์œ„ํ•ด์„œ Trie ๊ตฌ์กฐ ์‚ฌ์šฉ
68+
* - ์™€์ผ๋“œ์นด๋“œ(.)๊ฐ€ ํฌํ•จ๋œ ๋‹จ์–ด๋Š” ๋ชจ๋“  ์ž์‹ ๋…ธ๋“œ ํƒ์ƒ‰ํ•˜๊ธฐ ์œ„ํ•ด์„œ ์žฌ๊ท€์ ์œผ๋กœ ํ™•์ธ
69+
*
70+
* ์‹œ๊ฐ„๋ณต์žก๋„ : O(n * k)
71+
* - n : ๋‹จ์–ด ๊ฐœ์ˆ˜, m : ๋‹จ์–ด ํ‰๊ท  ๊ธธ์ด => addWord์˜ ๋ณต์žก๋„ : O(n * m)
72+
* - c : ์ž์‹๋…ธ๋“œ ๊ฐœ์ˆ˜, d : ์™€์ผ๋“œ์นด๋“œ ๊ฐœ์ˆ˜, m : ๋‹จ์–ด ๊ธธ์ด => search์˜ ๋ณต์žก๋„ : O(c^d * m)
73+
* - ์™€์ผ๋“œ ์นด๋“œ ์žˆ๋Š” ๊ฒฝ์šฐ ๊ฐ ๋…ธ๋“œ ๋ณ„ ๋ชจ๋“  ์ž์‹ ๋…ธ๋“œ๋ฅผ ํƒ์ƒ‰ํ•ด์•ผ ํ•œ๋‹ค.
74+
*
75+
* ๊ณต๊ฐ„๋ณต์žก๋„ : O(n * k)
76+
* - n์€ ํŒจํ„ด์˜ ๊ฐœ์ˆ˜, k๋Š” ํŒจํ„ด์— ๋งค์นญ๋˜๋Š” ํ‰๊ท  ๋‹จ์–ด ์ˆ˜
77+
*/
78+
class WordDictionary {
79+
root: TrieNode;
80+
constructor() {
81+
this.root = new TrieNode();
82+
}
83+
84+
addWord(word: string): void {
85+
let currentNode = this.root;
86+
87+
for (const letter of word) {
88+
if (!currentNode.children.has(letter))
89+
currentNode.children.set(letter, new TrieNode());
90+
currentNode = currentNode.children.get(letter)!;
91+
}
92+
93+
currentNode.isEndOfWord = true;
94+
}
95+
96+
search(word: string): boolean {
97+
const dfs = (currentNode: TrieNode, index: number): boolean => {
98+
if (index === word.length) return currentNode.isEndOfWord;
99+
100+
const char = word[index];
101+
// ์™€์ผ๋“œ ์นด๋“œ์ธ ๊ฒฝ์šฐ ๋ชจ๋“  ์ž์‹ ๋…ธ๋“œ ์ˆœํšŒํ•œ๋‹ค
102+
if (char === ".") {
103+
// ๋ชจ๋“  ์ž์‹ ๋…ธ๋“œ ์ˆœํšŒ
104+
for (const key of currentNode.children.keys()) {
105+
if (dfs(currentNode.children.get(key)!, index + 1)) return true;
106+
}
107+
return false;
108+
} else {
109+
if (!currentNode.children.has(char)) return false;
110+
return dfs(currentNode.children.get(char)!, index + 1);
111+
}
112+
};
113+
114+
return dfs(this.root, 0);
115+
}
116+
}
117+
118+
/**
119+
* Your WordDictionary object will be instantiated and called as such:
120+
* var obj = new WordDictionary()
121+
* obj.addWord(word)
122+
* var param_2 = obj.search(word)
123+
*/

0 commit comments

Comments
ย (0)