[Swift]LeetCode676. 實現一個魔法字典 | Implement Magic Dictionary

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公衆號:山青詠芝(shanqingyongzhi)
➤博客園地址:山青詠芝(https://www.cnblogs.com/strengthen/
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:http://www.javashuo.com/article/p-whdukztl-me.html 
➤若是連接不是山青詠芝的博客園地址,則多是爬取做者的文章。
➤原文已修改更新!強烈建議點擊原文地址閱讀!支持做者!支持原創!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★html

Implement a magic directory with buildDict, and search methods.node

For the method buildDict, you'll be given a list of non-repetitive words to build a dictionary.git

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.github

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:微信

  1. You may assume that all the inputs are consist of lowercase letters a-z.
  2. For contest purpose, the test data is rather small by now. You could think about highly efficient algorithm after the contest.
  3. 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方法的魔法字典。app

對於buildDict方法,你將被給定一串不重複的單詞來構建一個字典。測試

對於search方法,你將被給定一個單詞,而且斷定可否只將這個單詞中一個字母換成另外一個字母,使得所造成的新單詞存在於你構建的字典中。ui

示例 1:this

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

注意:

  1. 你能夠假設全部輸入都是小寫字母 a-z
  2. 爲了便於競賽,測試所用的數據量很小。你能夠在競賽結束後,考慮更高效的算法。
  3. 請記住重置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 }

Runtime: 72 ms
Memory Usage: 20 MB
 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  
相關文章
相關標籤/搜索