• [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  */
  • 相关阅读:
    UVA 10618 Tango Tango Insurrection
    UVA 10118 Free Candies
    HDU 1024 Max Sum Plus Plus
    POJ 1984 Navigation Nightmare
    CODEVS 3546 矩阵链乘法
    UVA 1625 Color Length
    UVA 1347 Tour
    UVA 437 The Tower of Babylon
    UVA 1622 Robot
    UVA127-"Accordian" Patience(模拟)
  • 原文地址:https://www.cnblogs.com/strengthen/p/10525441.html
Copyright © 2020-2023  润新知