zoukankan      html  css  js  c++  java
  • [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:

    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  
  • 相关阅读:
    steam
    node 循序渐进
    node 常用指令 node 扩展链接
    window 常用指令
    web API
    SHAREPOINT
    div设置边框黑框显示
    sharepoint更新多行文本webparth
    sharepoint读取启用了追加功能的多行文本的历史版本记录
    JS实现多附件上传(asp.net)
  • 原文地址:https://www.cnblogs.com/strengthen/p/10498012.html
Copyright © 2011-2022 走看看