[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 words
, words[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:
words
has length in range[1, 15000]
.- For each test case, up to
words.length
queriesWordFilter.f
may be made. words[i]
has length in range[1, 10]
.prefix, suffix
have lengths in range[0, 10]
.words[i]
andprefix, suffix
queries consist of lowercase letters only.
给定多个 words
,words[i]
的权重为 i
。
设计一个类 WordFilter
实现函数WordFilter.f(String prefix, String suffix)
。这个函数将返回具有前缀 prefix
和后缀suffix
的词的最大权重。如果没有这样的词,返回 -1。
例子:
输入: WordFilter(["apple"]) WordFilter.f("a", "e") // 返回 0 WordFilter.f("b", "") // 返回 -1
注意:
words
的长度在[1, 15000]
之间。- 对于每个测试用例,最多会有
words.length
次对WordFilter.f
的调用。 words[i]
的长度在[1, 10]
之间。prefix, suffix
的长度在[0, 10]
之前。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 */