为有牺牲多壮志,敢教日月换新天。

[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 
➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

热烈欢迎,请直接点击!!!

进入博主App Store主页,下载使用各个作品!!!

注:博主将坚持每月上线一个新app!!!

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:

  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方法的魔法字典。

对于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

注意:

  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  

 

posted @ 2019-03-08 20:22  为敢技术  阅读(383)  评论(0编辑  收藏  举报