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

[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 @   为敢技术  阅读(392)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示
哥伦布
09:09发布
哥伦布
09:09发布
3°
多云
东南风
3级
空气质量
相对湿度
47%
今天
中雨
3°/15°
周三
中雨
3°/13°
周四
小雪
-1°/6°