[Swift]LeetCode211. 新增與搜尋單詞 - 資料結構設計 | Add and Search Word - Data structure design
阿新 • • 發佈:2018-12-29
Design a data structure that supports the following two operations:
void addWord(word) bool search(word)
search(word) can search a literal word or a regular expression string containing only letters a-z
or .
. A .
means it can represent any one letter.
Example:
addWord("bad") addWord("dad") addWord("mad") search("pad") -> false search("bad") -> true search(".ad") -> true search("b..") -> true
Note:
You may assume that all words are consist of lowercase letters a-z
.
設計一個支援以下兩種操作的資料結構:
void addWord(word) bool search(word)
search(word) 可以搜尋文字或正則表示式字串,字串只包含字母 .
或 a-z
。 .
可以表示任何一個字母。
示例:
addWord("bad") addWord("dad") addWord("mad") search("pad") -> false search("bad") -> true search(".ad") -> true search("b..") -> true
說明:
你可以假設所有單詞都是由小寫字母 a-z
組成的。
612ms
1 class TrieNode { 2 var children: [Character: TrieNode] 3 var isEnd: Bool 4 5 init() { 6 children = [:] 7 isEnd = false 8 } 9 } 10 11 class WordDictionary { 12 13 private var root: TrieNode14 /** Initialize your data structure here. */ 15 init() { 16 root = TrieNode() 17 } 18 19 /** Adds a word into the data structure. */ 20 func addWord(_ word: String) { 21 var node = self.root 22 23 for c in Array(word) { 24 if let next = node.children[c] { 25 node = next 26 } else { 27 let newNode = TrieNode() 28 node.children[c] = newNode 29 node = newNode 30 } 31 } 32 node.isEnd = true 33 } 34 35 /** Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter. */ 36 func search(_ word: String) -> Bool { 37 return self.match(Array(word), 0, self.root) 38 } 39 40 private func match(_ chars: [Character], _ i :Int, _ node: TrieNode) -> Bool { 41 // if we reached the end 42 if i == chars.count { 43 return node.isEnd 44 } 45 let c = chars[i] 46 if c != "." { 47 guard let next = node.children[c] else { return false } 48 return self.match(chars, i + 1, next) 49 } else { 50 for next in node.children.values { 51 if self.match(chars, i + 1, next) { 52 return true 53 } 54 } 55 } 56 57 return false 58 } 59 } 60 61 /** 62 * Your WordDictionary object will be instantiated and called as such: 63 * let obj = WordDictionary() 64 * obj.addWord(word) 65 * let ret_2: Bool = obj.search(word) 66 */
620ms
1 class WordDictionary { 2 var trie = Trie() 3 4 /** Initialize your data structure here. */ 5 init() { 6 7 } 8 9 /** Adds a word into the data structure. */ 10 func addWord(_ word: String) { 11 trie.add(word: word) 12 } 13 14 /** Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter. */ 15 func search(_ word: String) -> Bool { 16 return trie.search(word:word) 17 } 18 } 19 20 class TrieNode { 21 var children: [Character: TrieNode] 22 var isEnd: Bool 23 24 init() { 25 self.children = [Character: TrieNode]() 26 self.isEnd = false 27 } 28 } 29 30 31 class Trie { 32 var root: TrieNode 33 34 init() { 35 root = TrieNode() 36 } 37 38 func add(word: String) { 39 var node = root 40 41 for char in word { 42 if node.children[char] == nil { 43 node.children[char] = TrieNode() 44 } 45 46 node = node.children[char]! 47 } 48 49 node.isEnd = true 50 } 51 52 func search(word:String) -> Bool { 53 return dfsSearch(word: word, index: 0, node: root) 54 } 55 56 fileprivate func dfsSearch(word: String, index: Int, node: TrieNode) -> Bool { 57 if index == word.count { 58 return node.isEnd 59 } 60 61 let char = Array(word)[index] 62 63 if char != "." { 64 guard let nextNode = node.children[char] else { 65 return false 66 } 67 68 return dfsSearch(word: word, index: index + 1, node: nextNode) 69 } else{ 70 for key in node.children.keys { 71 if dfsSearch(word: word, index: index + 1, node: node.children[key]!) { 72 return true 73 } 74 } 75 76 return false 77 } 78 } 79 } 80 /** 81 * Your WordDictionary object will be instantiated and called as such: 82 * let obj = WordDictionary() 83 * obj.addWord(word) 84 * let ret_2: Bool = obj.search(word) 85 */ 86
644ms
1 class TrieNode { 2 var children = [Character : TrieNode]() 3 var isEnd = false 4 } 5 6 7 class Trie { 8 private let root: TrieNode 9 10 /** Initialize your data structure here. */ 11 init() { 12 root = TrieNode() 13 } 14 15 /** Inserts a word into the trie. */ 16 func insert(_ word: String) { 17 var currentNode: TrieNode? = root 18 for c in word { 19 if let nextNode = currentNode?.children[c] { 20 currentNode = nextNode 21 } else { 22 let newNode = TrieNode() 23 24 currentNode?.children[c] = newNode 25 currentNode = newNode 26 } 27 } 28 29 currentNode?.isEnd = true 30 } 31 32 /** Returns if the word is in the trie. */ 33 func search(_ word: String) -> Bool { 34 return searchNode(root, word: word, index: word.startIndex) 35 } 36 37 func searchNode(_ node: TrieNode, word: String, index: String.Index) -> Bool { 38 if index == word.endIndex { 39 return node.isEnd 40 } 41 42 var currentNode: TrieNode? = root 43 let char = word[index] 44 if char == "." { 45 for (_, n) in node.children { 46 if searchNode(n, word: word, index: word.index(after: index)) { 47 return true 48 } 49 } 50 51 return false 52 } else { 53 guard let nextNode = node.children[char] else { 54 return false 55 } 56 57 return searchNode(nextNode, word: word, index: word.index(after: index)) 58 } 59 } 60 61 /** Returns if there is any word in the trie that starts with the given prefix. */ 62 func startsWith(_ prefix: String) -> Bool { 63 var currentNode: TrieNode? = root 64 for c in prefix { 65 guard let nextNode = currentNode?.children[c] else { 66 return false 67 } 68 69 currentNode = nextNode 70 } 71 72 return true 73 } 74 } 75 76 77 class WordDictionary { 78 private let trie = Trie() 79 80 81 /** Initialize your data structure here. */ 82 init() { 83 84 } 85 86 /** Adds a word into the data structure. */ 87 func addWord(_ word: String) { 88 trie.insert(word) 89 } 90 91 /** Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter. */ 92 func search(_ word: String) -> Bool { 93 return trie.search(word) 94 } 95 } 96 97 /** 98 * Your WordDictionary object will be instantiated and called as such: 99 * let obj = WordDictionary() 100 * obj.addWord(word) 101 * let ret_2: Bool = obj.search(word) 102 */ 103
756ms
1 class WordDictionary { 2 var trie = Trie() 3 /** Initialize your data structure here. */ 4 init() { 5 6 } 7 8 /** Adds a word into the data structure. */ 9 func addWord(_ word: String) { 10 trie.insert(word) 11 } 12 13 /** Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter. */ 14 func search(_ word: String) -> Bool { 15 return trie.search(word, 0, trie.root) 16 } 17 } 18 19 class TrieNode { 20 var isWord = false 21 var next = [Character: TrieNode]() 22 init(_ b: Bool = false) { 23 isWord = b 24 } 25 } 26 27 class Trie { 28 var root = TrieNode() 29 func insert(_ word: String) { 30 var cur = root 31 for c in word { 32 if cur.next[c] == nil { 33 cur.next[c] = TrieNode() 34 } 35 cur = cur.next[c]! 36 } 37 cur.isWord = true 38 } 39 40 func search(_ word: String, _ idx: Int, _ node: TrieNode) -> Bool { 41 var cur = node 42 var chars = Array(word) 43 for i in idx..<chars.count { 44 if let n = cur.next[chars[i]] { 45 cur = n 46 } else if chars[i] != "." { 47 return false 48 } else { 49 for n in cur.next.values { 50 if search(word, i+1, n) { 51 return true 52 } 53 } 54 return false 55 } 56 } 57 return cur.isWord 58 } 59 } 60 61 /** 62 * Your WordDictionary object will be instantiated and called as such: 63 * let obj = WordDictionary() 64 * obj.addWord(word) 65 * let ret_2: Bool = obj.search(word) 66 */ 67
764ms
1 class Trie { 2 var char: Character 3 var children: [Character :Trie] 4 5 init(_ char: Character) { 6 self.char = char 7 self.children = [:] 8 } 9 } 10 11 class WordDictionary { 12 var root: Trie 13 /** Initialize your data structure here. */ 14 init() { 15 self.root = Trie(Character(".")) 16 } 17 18 /** Adds a word into the data structure. */ 19 func addWord(_ word: String) { 20 var temp = root 21 for char in word { 22 if let child = temp.children[char] { 23 temp = child 24 } else { 25 let newNode = Trie(char) 26 temp.children[char] = newNode 27 temp = newNode 28 } 29 } 30 let newNode = Trie("$") 31 temp.children["$"] = newNode 32 temp = newNode 33 } 34 35 /** Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter. */ 36 func search(_ word: String) -> Bool { 37 return searchInternal(word, self.root) 38 } 39 40 private func searchInternal(_ word: String, _ node:Trie) -> Bool { 41 // print("Searching word : \(word)") 42 if word.isEmpty { 43 // print("Valid!!!!!!") 44 if let child = node.children["$"] { 45 return true 46 } else { 47 return false 48 } 49 } 50 let firstChar = word[word.index(word.startIndex, offsetBy: 0)] 51 let trimmedWord = String(word[word.index(word.startIndex, offsetBy: 1)..<word.endIndex]) 52 if firstChar == "." { 53 for child in node.children { 54 let isValidNode = self.searchInternal(trimmedWord, child.value) 55 if isValidNode { 56 return true 57 break 58 } 59 } 60 } else { 61 if let child = node.children[firstChar] { 62 return self.searchInternal(trimmedWord, child) 63 } else { 64 // print("not valid1") 65 return false 66 } 67 } 68 // print("not valid0") 69 return false 70 } 71 } 72 73 /** 74 * Your WordDictionary object will be instantiated and called as such: 75 * let obj = WordDictionary() 76 * obj.addWord(word) 77 * let ret_2: Bool = obj.search(word) 78 */ 79