745. Prefix and Suffix Search
https://leetcode.com/problems/prefix-and-suffix-search/
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.
对一系列词查询满足给定前缀和后缀的词的最大index。查词用Trie。但把每个可能的前缀和后缀的组合都放进trie空间会非常大。利用Trie找前缀很方便的性质,把单词不同后缀和整个单词拼在一起组成不同的新词放trie里,这样就不用针对所有可能的前缀单独放了。
代码参考自花花。
/*
* @lc app=leetcode id=745 lang=cpp
*
* [745] Prefix and Suffix Search
*
* https://leetcode.com/problems/prefix-and-suffix-search/description/
*
* algorithms
* Hard (31.50%)
* Likes: 237
* Dislikes: 165
* Total Accepted: 14.2K
* Total Submissions: 44.6K
* Testcase Example: '["WordFilter","f"]\n[[["apple"]],["a","e"]]'
*
* 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 queries WordFilter.f may be made.
* words[i] has length in range [1, 10].
* prefix, suffix have lengths in range [0, 10].
* words[i] and prefix, suffix queries consist of lowercase letters only.
*
*
*
*
*/
// @lc code=start
class WordFilter {
public:
class TrieNode {
public:
vector<TrieNode*> children;
bool word;
int index;
TrieNode(int ind): children(27, nullptr), word(false), index(ind) {}
};
TrieNode *root;
void insert(const string &w, int index) {
auto cur = root;
for (const auto c : w) {
const int i = c - 'a';
if (cur->children[i] == nullptr) cur->children[i] = new TrieNode(index);
cur = cur->children[i];
cur->index = index;
}
cur->word = true;
}
TrieNode* find(const string &prefix) {
auto cur = root;
for (const auto c : prefix) {
cur = cur->children[c - 'a'];
if (cur == nullptr) break;
}
return cur;
}
int query(const string &prefix) {
auto cur = find(prefix);
if (cur == nullptr) return -1;
return cur->index;
}
WordFilter(vector<string>& words) {
root = new TrieNode(-1);
for (int i = 0; i < words.size(); ++i) {
const auto &w = words[i];
auto key = "{" + w;
insert(key, i);
for (int j = 0; j < w.size(); ++j) {
key = w[w.size() - j - 1] + key;
insert(key, i);
}
}
}
int f(string prefix, string suffix) {
return query(suffix + "{" + prefix);
}
};
/**
* Your WordFilter object will be instantiated and called as such:
* WordFilter* obj = new WordFilter(words);
* int param_1 = obj->f(prefix,suffix);
*/
// @lc code=end
# Given many words, words[i] has weight i.
#
# Design a class WordFilter that supports one function, WordFilter.f(String pre
# fix, String suffix). It will return the word with given prefix and suffix with m
# aximum 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 queries WordFilter.f may be made.
# words[i] has length in range [1, 10].
# prefix, suffix have lengths in range [0, 10].
# words[i] and prefix, suffix queries consist of lowercase letters only.
#
#
#
# Related Topics Trie
# leetcode submit region begin(Prohibit modification and deletion)
class WordFilter(object):
class Trie(object):
def __init__(self):
"""
Initialize your data structure here.
"""
self.trie = {}
def insert(self, word, i):
"""
Inserts a word into the trie.
:type word: str
:rtype: dict
"""
cur = self.trie
for c in word:
if c not in cur:
cur[c] = {}
cur = cur[c]
cur['i'] = i
return cur
def startsWith(self, prefix):
"""
Returns if there is any word in the trie that starts with the given prefix.
:type prefix: str
:rtype: int
"""
cur = self.trie
for c in prefix:
if c not in cur:
return -1
cur = cur[c]
return cur['i']
def __init__(self, words):
"""
:type words: List[str]
"""
self.trie = WordFilter.Trie()
for weight, word in enumerate(words):
t = self.trie
t.insert(',' + word, weight)
for i in range(len(word)):
w = word[-i:]
t.insert(w + ',' + word, weight)
def f(self, prefix, suffix):
"""
:type prefix: str
:type suffix: str
:rtype: int
"""
return self.trie.startsWith(suffix + ',' + prefix)
# Your WordFilter object will be instantiated and called as such:
# obj = WordFilter(words)
# param_1 = obj.f(prefix,suffix)
# leetcode submit region end(Prohibit modification and deletion)
Last updated
Was this helpful?