|
| 1 | +package leetcode_study |
| 2 | + |
| 3 | + |
| 4 | +/* |
| 5 | +* 단어 사전을 만드는 문제. (찾는 단어는 wildcard가 포함될 수 있음) |
| 6 | +* https://www.youtube.com/watch?v=TohdsR58i3Q 동영상 참조 |
| 7 | +* trie 알고리즘을 사용한 문제 해결 |
| 8 | +* 시간 복잡도: O(L * 26) |
| 9 | +* -> addWord() 의 경우, 각 노드는 최대 26개의 노드를 가질 수 있으며 단어의 길이가 L이라면 O(L)의 시간 소요: O(L) |
| 10 | +* -> searchWord() 의 경우, 최악의 경우 모든 자식의 노드를 탐색해야 하므로 26(알파벳 수) 번의 탐색 진행: O(L * 26) |
| 11 | +* 공간 복잡도: O(n * L) |
| 12 | +* -> n 개의 단어, 평균적 단어 길이가 L일 경우 트리 노드에 저장된 노드의 수는 O(n * L) |
| 13 | +* */ |
| 14 | +class WordDictionary() { |
| 15 | + // Trie 노드 클래스 |
| 16 | + private class TrieNode { |
| 17 | + val children: MutableMap<Char, TrieNode> = mutableMapOf() |
| 18 | + var endOfWord: Boolean = false |
| 19 | + } |
| 20 | + |
| 21 | + private val root = TrieNode() |
| 22 | + |
| 23 | + // 단어를 트라이에 추가 |
| 24 | + fun addWord(word: String) { |
| 25 | + var currentNode = root |
| 26 | + for (char in word) { |
| 27 | + if (!currentNode.children.containsKey(char)) { |
| 28 | + currentNode.children[char] = TrieNode() // 해당 문자에 대한 새로운 노드 생성 |
| 29 | + } |
| 30 | + currentNode = currentNode.children[char]!! // point out next trie node |
| 31 | + } |
| 32 | + currentNode.endOfWord = true // 단어의 끝을 표시 |
| 33 | + } |
| 34 | + |
| 35 | + // 주어진 패턴을 검색 |
| 36 | + fun search(word: String): Boolean { |
| 37 | + return searchHelper(word, 0, root) |
| 38 | + } |
| 39 | + |
| 40 | + // 재귀적으로 단어를 검색하는 헬퍼 함수 |
| 41 | + private fun searchHelper(word: String, index: Int, node: TrieNode): Boolean { |
| 42 | + if (index == word.length) { |
| 43 | + return node.endOfWord // 단어의 끝에 도달했으면 해당 노드가 단어의 끝인지 확인 |
| 44 | + } |
| 45 | + |
| 46 | + val char = word[index] |
| 47 | + |
| 48 | + if (char == '.') { // '.'이면 모든 자식 노드에 대해 탐색 |
| 49 | + for (childNode in node.children.values) { |
| 50 | + if (searchHelper(word, index + 1, childNode)) { |
| 51 | + return true |
| 52 | + } |
| 53 | + } |
| 54 | + return false // '.'을 처리했지만 일치하는 노드가 없으면 false |
| 55 | + } else { |
| 56 | + // 현재 문자가 존재하는 자식 노드로 계속 탐색 |
| 57 | + val childNode = node.children[char] ?: return false |
| 58 | + return searchHelper(word, index + 1, childNode) |
| 59 | + } |
| 60 | + } |
| 61 | +} |
0 commit comments