zoukankan      html  css  js  c++  java
  • [Swift]LeetCode745. 前缀和后缀搜索 | Prefix and Suffix Search

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

    Given many wordswords[i] has weight i.

    Design a class WordFilter that supports one function, WordFilter.f(String prefix, String suffix). It will return the word with given prefix and suffix with maximum weight. If no word exists, return -1.

    Examples:

    Input:
    WordFilter(["apple"])
    WordFilter.f("a", "e") // returns 0
    WordFilter.f("b", "") // returns -1 

    Note:

    1. words has length in range [1, 15000].
    2. For each test case, up to words.length queries WordFilter.fmay be made.
    3. words[i] has length in range [1, 10].
    4. prefix, suffix have lengths in range [0, 10].
    5. words[i] and prefix, suffixqueries consist of lowercase letters only.

    给定多个 wordswords[i] 的权重为 i 。

    设计一个类 WordFilter 实现函数WordFilter.f(String prefix, String suffix)。这个函数将返回具有前缀 prefix 和后缀suffix 的词的最大权重。如果没有这样的词,返回 -1。

    例子:

    输入:
    WordFilter(["apple"])
    WordFilter.f("a", "e") // 返回 0
    WordFilter.f("b", "") // 返回 -1
    

    注意:

    1. words的长度在[1, 15000]之间。
    2. 对于每个测试用例,最多会有words.length次对WordFilter.f的调用。
    3. words[i]的长度在[1, 10]之间。
    4. prefix, suffix的长度在[0, 10]之前。
    5. words[i]prefix, suffix只包含小写字母。

    1760ms

     1 class Node {
     2     var map = [Character: Node]()
     3     var weights = [Int]()
     4 }
     5 
     6 class WordFilter {
     7     private var maxDepth = 10
     8     private var forwardRoot = Node()
     9     private var backwardRoot = Node()
    10     init(_ words: [String]) {
    11         var forwardNode: Node?
    12         var backwardNode: Node?
    13         for (wIndex, word)in words.enumerated() {
    14             forwardNode = forwardRoot
    15             for char in word {
    16                 if forwardNode?.map[char] == nil {
    17                     forwardNode?.map[char] = Node()
    18                 }
    19                 forwardNode?.weights.append(wIndex)
    20                 forwardNode = forwardNode?.map[char]
    21             }
    22             forwardNode?.weights.append(wIndex)
    23 
    24             backwardNode = backwardRoot
    25             for char in word.reversed() {
    26                 if backwardNode?.map[char] == nil {
    27                     backwardNode?.map[char] = Node()
    28                 }
    29                 backwardNode?.weights.append(wIndex)
    30                 backwardNode = backwardNode?.map[char]
    31             }
    32             backwardNode?.weights.append(wIndex)
    33         }
    34     }
    35 
    36     func f(_ prefix: String, _ suffix: String) -> Int {
    37         var forwardNode: Node? = forwardRoot
    38         for char in prefix {
    39             guard let node = forwardNode else { break }
    40             forwardNode = node.map[char]
    41         }
    42 
    43         guard let fWeights = forwardNode?.weights,
    44             fWeights.count > 0 else { return -1 }
    45 
    46         var backwardNode: Node? = backwardRoot
    47         for char in suffix.reversed() {
    48             guard let node = backwardNode else { break }
    49             backwardNode = node.map[char]
    50         }
    51 
    52         guard let bWeights = backwardNode?.weights,
    53             bWeights.count > 0 else { return -1 }
    54 
    55         var fIndex = fWeights.count - 1
    56         var bIndex = bWeights.count - 1
    57 
    58         while fIndex >= 0, bIndex >= 0 {
    59             let fw = fWeights[fIndex]
    60             let bw = bWeights[bIndex]
    61             if fw == bw {
    62                 return fw
    63             }
    64             if fw > bw {
    65                 fIndex -= 1
    66             } else {
    67                 bIndex -= 1
    68             }
    69         }
    70         return -1
    71     }
    72 }
    73 
    74 /**
    75  * Your WordFilter object will be instantiated and called as such:
    76  * let obj = WordFilter(words)
    77  * let ret_1: Int = obj.f(prefix, suffix)
    78  */

    Runtime: 1768 ms
    Memory Usage: 23.1 MB
     1 class WordFilter {
     2     var mp:[String:[Int]] = [String:[Int]]()
     3     var ms:[String:[Int]] = [String:[Int]]()
     4 
     5     init(_ words: [String]) {
     6         for k in 0..<words.count
     7         {
     8             for i in 0...words[k].count
     9             {
    10                 mp[words[k].subString(0, i),default:[Int]()].append(k)
    11             }
    12             for i in 0...words[k].count
    13             {
    14                 ms[words[k].subString(words[k].count - i),default:[Int]()].append(k)
    15             }
    16         }
    17         
    18     }
    19     
    20     func f(_ prefix: String, _ suffix: String) -> Int {
    21         if mp[prefix] == nil || ms[suffix] == nil {return -1}
    22         var pre:[Int] = mp[prefix]!
    23         var suf:[Int] = ms[suffix]!
    24         var i:Int = pre.count - 1
    25         var j:Int = suf.count - 1
    26         while (i >= 0 && j >= 0)
    27         {
    28             if pre[i] < suf[j]
    29             {
    30                 j -= 1
    31             }
    32             else if pre[i] > suf[j]
    33             {
    34                 i -= 1
    35             }
    36             else
    37             {
    38                 return pre[i]
    39             }            
    40         }       
    41         return -1      
    42     }
    43 }
    44 
    45 /**
    46  * Your WordFilter object will be instantiated and called as such:
    47  * let obj = WordFilter(words)
    48  * let ret_1: Int = obj.f(prefix, suffix)
    49  */
    50  
    51 extension String {
    52     // 截取字符串:指定索引和字符数
    53     // - begin: 开始截取处索引
    54     // - count: 截取的字符数量
    55     func subString(_ begin:Int,_ count:Int) -> String {
    56         let start = self.index(self.startIndex, offsetBy: max(0, begin))
    57         let end = self.index(self.startIndex, offsetBy:  min(self.count, begin + count))
    58         return String(self[start..<end]) 
    59     }   
    60     
    61     // 截取字符串:从index到结束处
    62     // - Parameter index: 开始索引
    63     // - Returns: 子字符串
    64     func subString(_ index: Int) -> String {
    65         let theIndex = self.index(self.endIndex, offsetBy: index - self.count)
    66         return String(self[theIndex..<endIndex])
    67     }
    68 }

    2024ms

     1 class WordFilter {
     2 
     3     var map: [String: Int] = [:]
     4     
     5     init(_ words: [String]) {
     6         for i in 0 ..< words.count {
     7             insert(words[i], i)
     8         }
     9     }
    10     
    11     private func insert(_ word: String, _ index: Int) {
    12         var preList = [Substring]()
    13         var sufList = [Substring]()
    14         for i in 0 ... word.count {
    15             preList.append(word.prefix(i))
    16             sufList.append(word.suffix(i))
    17         }
    18         for x in preList {
    19             for y in sufList {
    20                 map["(x)_(y)"] = index
    21             }
    22         }
    23     }
    24     
    25     func f(_ prefix: String, _ suffix: String) -> Int {
    26         return map["(prefix)_(suffix)"] ?? -1
    27     }
    28 }
    29 
    30 /**
    31  * Your WordFilter object will be instantiated and called as such:
    32  * let obj = WordFilter(words)
    33  * let ret_1: Int = obj.f(prefix, suffix)
    34  */

    2200ms

     1 class WordFilter {
     2     
     3     private class TrieNode {
     4         var children = [Character: TrieNode]()
     5         var index = -1
     6     }
     7     
     8     private var root: TrieNode
     9     
    10     init(_ words: [String]) {
    11         root = TrieNode()
    12         for i in 0 ..< words.count {
    13             insert(words[i], i)
    14         }
    15     }
    16     
    17     func insert(_ word: String, _ idx: Int) {
    18         let len = word.count
    19         let start = word.startIndex
    20         var i = len
    21         while i >= 0 {
    22             let newWord = word.substring(from: word.index(start, offsetBy: i))
    23             insertReal("(newWord)_(word)", idx)
    24             i -= 1
    25         }
    26     }
    27     
    28     func insertReal(_ word: String, _ idx: Int) {
    29         var p = root
    30         for c in word {
    31             if p.children[c] == nil {
    32                 p.children[c] = TrieNode()
    33             }
    34             p = p.children[c]!
    35             p.index = idx
    36         }
    37     }
    38     
    39     func startWith(_ prefix: String) -> Int {
    40         var p = root
    41         for c in prefix {
    42             if let node = p.children[c] {
    43                 p = node
    44             } else {
    45                 return -1
    46             }
    47         }
    48         
    49         return p.index
    50     }
    51     
    52     func f(_ prefix: String, _ suffix: String) -> Int {
    53         return startWith("(suffix)_(prefix)")
    54     }
    55 }
    56 
    57 
    58 /**
    59  * Your WordFilter object will be instantiated and called as such:
    60  * let obj = WordFilter(words)
    61  * let ret_1: Int = obj.f(prefix, suffix)
    62  */

    Time Limit Exceeded 
     1 class WordFilter {
     2     var input:[String] = [String]()
     3 
     4     init(_ words: [String]) {
     5         input = words        
     6     }
     7     
     8     func f(_ prefix: String, _ suffix: String) -> Int {
     9         //注意enumerated()、reversed()的顺序
    10         for (index,str) in input.enumerated().reversed()
    11         {
    12             if str.hasPrefix(prefix) && str.hasSuffix(suffix)
    13             {
    14                 return index
    15             }            
    16         }    
    17         return -1      
    18     }
    19 }
    20 
    21 /**
    22  * Your WordFilter object will be instantiated and called as such:
    23  * let obj = WordFilter(words)
    24  * let ret_1: Int = obj.f(prefix, suffix)
    25  */
  • 相关阅读:
    Babelfish
    【动态规划】货币面值
    contest 1.18
    contest 1.17
    contest 1.16
    contest 1.15
    contest 1.14
    contest 1.13
    contest 12.31
    [cf]Round #529 (Div. 3)
  • 原文地址:https://www.cnblogs.com/strengthen/p/10525441.html
Copyright © 2011-2022 走看看