为有牺牲多壮志,敢教日月换新天。

[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 
➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

热烈欢迎,请直接点击!!!

进入博主App Store主页,下载使用各个作品!!!

注:博主将坚持每月上线一个新app!!!

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  */

 

posted @ 2019-03-13 19:07  为敢技术  阅读(935)  评论(0编辑  收藏  举报