zoukankan      html  css  js  c++  java
  • [Swift]LeetCode648. 单词替换 | Replace Words

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
    ➤微信公众号:山青咏芝(shanqingyongzhi)
    ➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/
    ➤GitHub地址:https://github.com/strengthen/LeetCode
    ➤原文地址:https://www.cnblogs.com/strengthen/p/10485210.html 
    ➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
    ➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

    In English, we have a concept called root, which can be followed by some other words to form another longer word - let's call this word successor. For example, the root an, followed by other, which can form another word another.

    Now, given a dictionary consisting of many roots and a sentence. You need to replace all the successor in the sentence with the root forming it. If a successor has many roots can form it, replace it with the root with the shortest length.

    You need to output the sentence after the replacement.

    Example 1:

    Input: dict = ["cat", "bat", "rat"]
    sentence = "the cattle was rattled by the battery"
    Output: "the cat was rat by the bat" 

    Note:

    1. The input will only have lower-case letters.
    2. 1 <= dict words number <= 1000
    3. 1 <= sentence words number <= 1000
    4. 1 <= root length <= 100
    5. 1 <= sentence words length <= 1000

    在英语中,我们有一个叫做 词根(root)的概念,它可以跟着其他一些词组成另一个较长的单词——我们称这个词为 继承词(successor)。例如,词根an,跟随着单词 other(其他),可以形成新的单词 another(另一个)。

    现在,给定一个由许多词根组成的词典和一个句子。你需要将句子中的所有继承词词根替换掉。如果继承词有许多可以形成它的词根,则用最短的词根替换它。

    你需要输出替换之后的句子。

    示例 1:

    输入: dict(词典) = ["cat", "bat", "rat"]
    sentence(句子) = "the cattle was rattled by the battery"
    输出: "the cat was rat by the bat"
    

    注:

    1. 输入只包含小写字母。
    2. 1 <= 字典单词数 <=1000
    3. 1 <=  句中词语数 <= 1000
    4. 1 <= 词根长度 <= 100
    5. 1 <= 句中词语长度 <= 1000

    448ms

     1 class Solution {
     2     
     3     private let trie = Trie()
     4     
     5     func replaceWords(_ dict: [String], _ sentence: String) -> String {
     6         dict.forEach { word in
     7             trie.insert(word)
     8         }
     9         
    10         var words = [String]()
    11         sentence.split(separator: " ").forEach { word in
    12             words.append(trie.replacement(String(word)))
    13         }
    14         return words.joined(separator: " ")
    15     }    
    16 }
    17 
    18 class Trie {
    19     
    20     private let root = TrieNode()
    21     
    22     func insert(_ word: String) {
    23         var node = root
    24         word.forEach { c in
    25             let next = node.insert(c)
    26             node = next
    27         }
    28         node.len = word.count
    29     }
    30     
    31     func replacement(_ word: String) -> String {
    32         var replace = ""
    33         var node = root
    34         for c in word {
    35             guard let next = node.search(c) else {
    36                 break
    37             }
    38             replace += String(c)
    39             if next.len > 0 {
    40                 return replace
    41             }
    42             node = next
    43         }
    44         return word
    45     }    
    46 }
    47 
    48 class TrieNode {
    49     
    50     var len = 0
    51     private var map = [Character: TrieNode]()
    52     
    53     func search(_ c: Character) -> TrieNode? {
    54         return map[c]
    55     }
    56     
    57     func insert(_ c: Character) -> TrieNode {
    58         if let node = map[c] {
    59             return node
    60         }
    61         let node = TrieNode()
    62         map[c] = node
    63         return node
    64     }    
    65 }

    532ms

     1 class Solution {
     2     func replaceWords(_ dict: [String], _ sentence: String) -> String {
     3         var trie = Trie()
     4         
     5         for word in dict {
     6             trie.insert(word)
     7         }
     8         
     9         var arr = sentence.split(separator: Character(" "))
    10         var res = [String]()
    11         for word in arr {
    12             res.append(trie.searchForAbbr(String(word)))
    13         }
    14         return res.joined(separator: " ")
    15     }
    16 }
    17 
    18 class Trie {
    19     class TrieNode: CustomStringConvertible {
    20         var description: String {
    21             return "(char) children: (children.keys)"
    22         }
    23         
    24         var char: Character = Character(" ")
    25         var isWordEnding: Bool = false
    26         var children: [Character: TrieNode] = [Character: TrieNode]()
    27         
    28         init(char: Character = " ", isWordEnding: Bool = false, children: [Character: TrieNode] = [:]) {
    29             self.char = char
    30             self.isWordEnding = isWordEnding
    31             self.children = children
    32         }
    33     }
    34     var root: TrieNode
    35     /** Initialize your data structure here. */
    36     init() {
    37         root = TrieNode()
    38     }
    39     func searchForAbbr(_ word: String) -> String {
    40         var str = ""
    41         var cur = root
    42         for (index,c) in word.enumerated() {
    43             str = str + String(c)
    44             if cur.children[c] == nil {
    45                 return word
    46             } else {
    47                 let next = cur.children[c]!
    48                 if(next.isWordEnding) {
    49                     return str
    50                 }
    51                 cur = next
    52             }
    53         }
    54         return word
    55     }
    56     /** Inserts a word into the trie. */
    57     func insert(_ word: String) {
    58         var cur = root
    59         for (index, c) in word.enumerated() {
    60             if cur.children[c] == nil {
    61                 cur.children[c] = TrieNode(char: c, isWordEnding: index == word.count - 1 , children: [:])
    62             } else {
    63                 if index == word.count - 1 {
    64                     cur.children[c]!.isWordEnding = true
    65                 }
    66             }
    67             cur = cur.children[c]!
    68         }
    69     }
    70     
    71     /** Returns if the word is in the trie. */
    72     func search(_ word: String) -> TrieNode? {
    73         var cur = root
    74         
    75         for c in word {
    76             if cur.children[c] == nil {
    77                 return nil
    78             } else {
    79                 let next = cur.children[c]!
    80                 cur = next
    81             }
    82         }
    83         return cur
    84     }
    85     
    86     /** Returns if there is any word in the trie that starts with the given prefix. */
    87     func startsWith(_ prefix: String) -> Bool {
    88         var cur = root
    89         for c in prefix {
    90             if cur.children[c] == nil {
    91                 return false
    92             }
    93             cur = cur.children[c]!
    94         }
    95         return true
    96     }
    97 }

    544ms

     1 class Solution {
     2     class TrieNode {
     3         var terminal = false
     4         var children = [Character: TrieNode]()
     5     }
     6     
     7     class Trie {
     8         var root = TrieNode()
     9 
    10         func addWord(_ word: String) {
    11             var n = root
    12             for ch in word.characters {
    13                 if let child = n.children[ch] {
    14                     n = child
    15                 } else {
    16                     let newNode = TrieNode()
    17                     n.children[ch] = newNode
    18                     n = newNode
    19                 }
    20             }
    21             n.terminal = true
    22         }
    23         
    24         func getWordRoot(_ word: String) -> String {
    25             var n = root
    26             let arr = Array(word.characters)
    27             for i in 0..<arr.count {
    28                 guard let child = n.children[arr[i]] else { return word }
    29                 n = child
    30                 if n.terminal {
    31                     return String(arr[...i])
    32                 }
    33             }
    34             return word
    35         }
    36     }
    37     
    38     func replaceWords(_ dict: [String], _ sentence: String) -> String {
    39         let trie = Trie()
    40         dict.forEach{ trie.addWord($0) }
    41         
    42         let words = Array(sentence.components(separatedBy: " "))
    43         return words.map{ trie.getWordRoot($0) }.joined(separator: " ")
    44     }
    45 }

    Runtime: 548 ms
    Memory Usage: 22.9 MB
     1 class Solution {
     2     func replaceWords(_ dict: [String], _ sentence: String) -> String {
     3         var dict = dict
     4         var res:String = String()
     5         var t:String = String()
     6         var v:[[String]] = [[String]](repeating:[String](),count:26)
     7         var arr:[String] = sentence.components(separatedBy:" ")
     8         dict = dict.sorted { $0.count < $1.count }
     9         for word in dict
    10         {
    11             v[word[0].ascii - 97].append(word)
    12         }
    13         for str in arr
    14         {
    15             t = str
    16             for word in v[t[0].ascii - 97]
    17             {
    18                 if t.subString(0, word.count) == word
    19                 {
    20                     t = word
    21                     break
    22                 }
    23             }
    24             res += t + " "
    25         }
    26         res.removeLast()
    27         return res
    28     }
    29 }
    30 
    31 //String扩展
    32 extension String {        
    33     //subscript函数可以检索数组中的值
    34     //直接按照索引方式截取指定索引的字符
    35     subscript (_ i: Int) -> Character {
    36         //读取字符
    37         get {return self[index(startIndex, offsetBy: i)]}
    38     }
    39     
    40     // 截取字符串:指定索引和字符数
    41     // - begin: 开始截取处索引
    42     // - count: 截取的字符数量
    43     func subString(_ begin:Int,_ count:Int) -> String {
    44         let start = self.index(self.startIndex, offsetBy: max(0, begin))
    45         let end = self.index(self.startIndex, offsetBy:  min(self.count, begin + count))
    46         return String(self[start..<end]) 
    47     }
    48 }
    49 
    50 //Character扩展 
    51 extension Character  
    52 {  
    53   //Character转ASCII整数值(定义小写为整数值)
    54    var ascii: Int {
    55        get {
    56            return Int(self.unicodeScalars.first?.value ?? 0)
    57        }       
    58     }    
    59 }

    568ms

     1 class Solution {
     2     class Node {
     3         var value: Character?
     4         var children: [Character : Node] = [:]
     5         var isTerminating = false
     6         
     7         init(value: Character? = nil) {
     8             self.value = value
     9         }
    10         
    11         func add(_ letter: Character) {
    12             guard children[letter] == nil else { return }
    13             children[letter] = Node(value: letter)
    14         }
    15     }
    16     
    17     var root = Node()
    18     
    19     func addWord(_ word: String) {
    20         guard !word.isEmpty else { return }
    21         
    22         var currentNode = root
    23         
    24         for letter in word {
    25             if currentNode.children[letter] == nil {
    26                 currentNode.add(letter)
    27             }
    28             
    29             guard let node = currentNode.children[letter] else { continue }
    30             currentNode = node
    31         }
    32         
    33         currentNode.isTerminating = true
    34     }
    35     
    36     func findRoot(_ word: String) -> String? {
    37         var result = ""
    38         var currentNode = root
    39         
    40         for letter in word {
    41             if let node = currentNode.children[letter] {
    42                 currentNode = node
    43                 if let value = node.value {
    44                      result += String(value)
    45                 }
    46                 
    47                 if currentNode.isTerminating {
    48                     return result
    49                 }
    50             } else {
    51                 if currentNode.isTerminating {
    52                     return result
    53                 } else {
    54                     return nil
    55                 }
    56             }
    57         }
    58         
    59         return result.isEmpty ? nil : result
    60     }
    61     
    62     func replaceWords(_ dict: [String], _ sentence: String) -> String {
    63         var result = ""
    64         
    65         for word in dict {
    66             addWord(word)
    67         }
    68         
    69         var currentWord = ""
    70         
    71         for char in sentence {
    72             if char == " " {
    73                 result += (findRoot(currentWord) ?? currentWord) + " "
    74                 currentWord = ""   
    75             } else {
    76                 currentWord += String(char)
    77             }
    78         }
    79         
    80         result += findRoot(currentWord) ?? currentWord
    81         return result
    82     }
    83 }

    632ms

     1 class Solution {
     2     class TrieNode<Key : Hashable>{
     3     public var key : Key?
     4     public var isTerminating : Bool = false
     5     public var children : [Key : TrieNode] = [:]
     6     public init(_ key : Key?){
     7         self.key = key
     8     }
     9 }
    10 
    11 func replaceWords(_ dict: [String], _ sentence: String) -> String {
    12     let trie = Trie<String>.init()
    13     for str in dict{
    14         trie.insert(str)
    15     }
    16     var results : [String] = []
    17     let components = sentence.components(separatedBy: " ")
    18     for component in components{
    19         if let replacement = trie.findPrefixesWithCollection(component, prefix: ""){
    20             results.append(replacement)
    21         }else{
    22             results.append(component)
    23         }
    24     }
    25     
    26     return results.joined(separator: " ")
    27 }
    28 
    29 class Trie<CollectionType : RangeReplaceableCollection> where CollectionType.Element : Hashable{
    30     public typealias Node = TrieNode<CollectionType.Element>
    31     private let root = Node.init(nil)
    32     public init(){}
    33     
    34     // Insertion
    35     public func insert(_ collection : CollectionType){
    36         var current = root
    37         for element in collection{
    38             if current.children[element] == nil{
    39                 current.children[element] = Node.init(element)
    40             }
    41             current = current.children[element]!
    42         }
    43         current.isTerminating = true
    44     }
    45     
    46     public func findPrefixesWithCollection(_ collection : CollectionType, prefix : CollectionType)->CollectionType?{
    47         var current = root
    48         var result = prefix
    49         
    50         for element in collection{
    51             if current.isTerminating == true{
    52                 break
    53             }else{
    54                 if current.children[element] == nil{
    55                     return nil
    56                 }else{
    57                     result.append(element)
    58                     current = current.children[element]!
    59                 }
    60             }
    61         }
    62         // now we have gotten the shortest word
    63         return result
    64     }
    65   }
    66 }

    692ms

     1 class Solution {
     2     func replaceWords(_ dict: [String], _ sentence: String) -> String {
     3         let trie = Trie()
     4         for root in dict {
     5             trie.insert(root)
     6         }
     7         
     8         var retval: [String] = []
     9         let words = sentence.components(separatedBy: " ")
    10         for word in words {
    11             retval.append(trie.startsWith(word) ?? word)
    12         }
    13         return retval.joined(separator: " ")
    14     }
    15 }
    16 
    17 
    18 
    19 class TrieNode {
    20     var key: Character?
    21     var children: [Character: TrieNode] = [:]
    22     var isTerminator = false
    23     
    24     init() {
    25     }
    26     
    27     init(_ key: Character) {
    28         self.key = key
    29     }
    30 }
    31 
    32 
    33 class Trie {
    34     private let root: TrieNode 
    35     /** Initialize your data structure here. */
    36     init() {
    37         root = TrieNode()
    38     }
    39     
    40     /** Inserts a word into the trie. */
    41     func insert(_ word: String) {
    42         var node = root
    43         for char in word {
    44             if let some = node.children[char] {
    45                 node = some
    46             } else {
    47                 let n = TrieNode(char)
    48                 node.children[char] = n
    49                 node = n
    50             }
    51         }
    52         node.isTerminator = true
    53     }
    54     
    55     /** Returns if there is any word in the trie that starts with the given prefix. */
    56     func startsWith(_ prefix: String) -> String? {
    57       var retVal = ""
    58       var node = root
    59         for char in prefix {
    60             if let some = node.children[char] {
    61                 node = some
    62                 retVal.append(node.key!)
    63                 if node.isTerminator {
    64                     return retVal
    65                 }
    66             } else {
    67                 return nil
    68             }
    69         }
    70         return retVal
    71     }
    72 }
  • 相关阅读:
    Map和Set
    js基本语法入门
    js中变量的作用域,let,const详解
    循环结构
    方法
    只有分享才能一起进步
    培训随笔
    得食相呼,义也
    Wall.e
    《国学之大智慧》观感
  • 原文地址:https://www.cnblogs.com/strengthen/p/10485210.html
Copyright © 2011-2022 走看看