[Swift]LeetCode676. 实现一个魔法字典 | Implement Magic Dictionary
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公众号:山青咏芝(shanqingyongzhi)
➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/)
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:https://www.cnblogs.com/strengthen/p/10498012.html
➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
Implement a magic directory with buildDict
, and search
methods.
For the method buildDict
, you'll be given a list of non-repetitive words to build a dictionary.
For the method search
, you'll be given a word, and judge whether if you modify exactly one character into another character in this word, the modified word is in the dictionary you just built.
Example 1:
Input: buildDict(["hello", "leetcode"]), Output: Null Input: search("hello"), Output: False Input: search("hhllo"), Output: True Input: search("hell"), Output: False Input: search("leetcoded"), Output: False
Note:
- You may assume that all the inputs are consist of lowercase letters
a-z
. - For contest purpose, the test data is rather small by now. You could think about highly efficient algorithm after the contest.
- Please remember to RESET your class variables declared in class MagicDictionary, as static/class variables are persisted across multiple test cases. Please see herefor more details.
实现一个带有buildDict
, 以及 search
方法的魔法字典。
对于buildDict
方法,你将被给定一串不重复的单词来构建一个字典。
对于search
方法,你将被给定一个单词,并且判定能否只将这个单词中一个字母换成另一个字母,使得所形成的新单词存在于你构建的字典中。
示例 1:
Input: buildDict(["hello", "leetcode"]), Output: Null Input: search("hello"), Output: False Input: search("hhllo"), Output: True Input: search("hell"), Output: False Input: search("leetcoded"), Output: False
注意:
- 你可以假设所有输入都是小写字母
a-z
。 - 为了便于竞赛,测试所用的数据量很小。你可以在竞赛结束后,考虑更高效的算法。
- 请记住重置MagicDictionary类中声明的类变量,因为静态/类变量会在多个测试用例中保留。 请参阅这里了解更多详情。
8ms
1 class MagicDictionary { 2 var map = [Int: Set<String>]() 3 /** Initialize your data structure here. */ 4 init() { 5 6 } 7 8 /** Build a dictionary through a list of words */ 9 func buildDict(_ dict: [String]) { 10 map.removeAll() 11 for str in dict { 12 var sets = map[str.count, default: Set<String>()] 13 sets.insert(str) 14 map[str.count] = sets 15 } 16 } 17 18 /** Returns if there is any word in the trie that equals to the given word after modifying exactly one character */ 19 func search(_ word: String) -> Bool { 20 let sets = map[word.count, default: Set<String>()] 21 let srcChars = Array(word) 22 for str in sets { 23 var diffct = 0 24 let curChars = Array(str) 25 for i in 0..<word.count { 26 if srcChars[i] != curChars[i] { diffct += 1 } 27 if diffct > 1 { break } 28 } 29 if diffct == 1 { return true } 30 } 31 return false 32 } 33 } 34 35 /** 36 * Your MagicDictionary object will be instantiated and called as such: 37 * let obj = MagicDictionary() 38 * obj.buildDict(dict) 39 * let ret_2: Bool = obj.search(word) 40 */
16ms
1 class MagicDictionary { 2 private var dictionary : [Int : [String]] = [:] 3 /** Initialize your data structure here. */ 4 init() { 5 6 } 7 8 /** Build a dictionary through a list of words */ 9 func buildDict(_ dict: [String]) { 10 for str in dict{ 11 if dictionary[str.count] == nil{ 12 dictionary[str.count] = [str] 13 }else{ 14 dictionary[str.count]!.append(str) 15 } 16 17 } 18 } 19 20 /** Returns if there is any word in the trie that equals to the given word after modifying exactly one character */ 21 func search(_ word: String) -> Bool { 22 guard let words = dictionary[word.count] else{ 23 return false 24 } 25 26 for str in words{ 27 if isOneDifference(Array(str), Array(word)){ 28 return true 29 } 30 } 31 return false 32 } 33 34 private func isOneDifference(_ first : [Character], _ second : [Character])->Bool{ 35 guard first.count == second.count else{ 36 return false 37 } 38 var movingIndex : Int = 0 39 var diffCount : Int = 0 40 41 while movingIndex < first.count{ 42 if first[movingIndex] != second[movingIndex]{ 43 if diffCount == 1{ 44 return false 45 } 46 diffCount += 1 47 } 48 movingIndex += 1 49 } 50 51 return diffCount == 1 52 } 53 }
20ms
1 class MagicDictionary { 2 3 4 var trie: Trie 5 6 /** Initialize your data structure here. */ 7 init() { 8 self.trie = Trie() 9 } 10 11 /** Build a dictionary through a list of words */ 12 func buildDict(_ dict: [String]) { 13 dict.forEach{ self.trie.insert($0) } 14 15 } 16 17 /** Returns if there is any word in the trie that equals to the given word after modifying exactly one character */ 18 func search(_ word: String) -> Bool { 19 20 let wordArray = word.map{ String($0) } 21 22 return self.trie.search(wordArray, errorCount: 0) 23 } 24 } 25 26 class Trie { 27 28 var roots: [String: Node] 29 30 init() { 31 self.roots = [String: Node]() 32 } 33 34 func search(_ word: [String], errorCount: Int) -> Bool { 35 36 guard let first = word.first else { return false } 37 38 var result = false 39 self.roots.forEach{ (key, value) in 40 41 let newResult = search(word, at: value, errorCount: errorCount) 42 result = result || newResult 43 44 } 45 46 return result 47 } 48 49 func search(_ word: [String], at node: Node, errorCount: Int) -> Bool { 50 51 guard let first = word.first else { return errorCount == 1 } 52 53 if first != node.char && errorCount >= 1 { return false } 54 55 var errorCount = errorCount 56 if first != node.char { errorCount += 1 } 57 58 if word.count == 1 && errorCount == 1 && node.isWord { return true } 59 60 var newWord = word 61 newWord.removeFirst() 62 63 if let next = newWord.first { 64 let allChilds = node.childs 65 var result = false 66 allChilds.forEach{ (key, value) in 67 let newResult = search(newWord, at: value, errorCount: errorCount) 68 result = result || newResult 69 } 70 71 return result 72 } 73 return false 74 } 75 76 77 func insert(_ word: String) { 78 var wordArray = word.map{ String($0) } 79 guard let first = wordArray.first else { return } 80 var node = self.roots[first] ?? Node(first) 81 self.roots[first] = insert(wordArray, at: node) 82 } 83 84 85 func insert(_ word: [String], at node: Node) -> Node { 86 87 guard let first = word.first else { return node } 88 guard first == node.char else { return node } 89 90 if word.count == 1 { 91 node.isWord = true 92 return node 93 } 94 95 var newWord = word 96 newWord.removeFirst() 97 98 let next = newWord.first! 99 100 let child = node.childs[next] ?? Node(next) 101 102 let newChild = insert(newWord, at: child) 103 104 node.childs[next] = newChild 105 106 return node 107 } 108 109 } 110 111 class Node { 112 113 let char: String 114 var isWord = false 115 var childs: [String: Node] 116 117 init(_ char: String) { 118 119 self.char = char 120 self.childs = [String: Node]() 121 } 122 }
1 class MagicDictionary { 2 var s:Set<String> 3 4 /** Initialize your data structure here. */ 5 init() { 6 s = Set<String>() 7 } 8 9 /** Build a dictionary through a list of words */ 10 func buildDict(_ dict: [String]) { 11 for word in dict 12 { 13 s.insert(word) 14 } 15 } 16 17 /** Returns if there is any word in the trie that equals to the given word after modifying exactly one character */ 18 func search(_ word: String) -> Bool { 19 var word = word 20 var arr:[Character] = Array(word) 21 for i in 0..<arr.count 22 { 23 var t:Character = arr[i] 24 for c in 97...122 25 { 26 var char = c.ASCII 27 if char == t {continue} 28 arr[i] = char 29 word = String(arr) 30 if s.contains(word) 31 { 32 return true 33 } 34 } 35 arr[i] = t 36 } 37 return false 38 } 39 } 40 41 //Int扩展 42 extension Int 43 { 44 //Int转Character,ASCII值(定义大写为字符值) 45 var ASCII:Character 46 { 47 get {return Character(UnicodeScalar(self)!)} 48 } 49 } 50 /** 51 * Your MagicDictionary object will be instantiated and called as such: 52 * let obj = MagicDictionary() 53 * obj.buildDict(dict) 54 * let ret_2: Bool = obj.search(word) 55 */ 56