0745. Prefix and Suffix Search (H)
Prefix and Suffix Search (H)
题目
Design a special dictionary which has some words and allows you to search the words in it by a prefix and a suffix.
Implement the WordFilter
class:
WordFilter(string[] words)
Initializes the object with thewords
in the dictionary.f(string prefix, string suffix)
Returns the index of the word in the dictionary which has the prefixprefix
and the suffixsuffix
. If there is more than one valid index, return the largest of them. If there is no such word in the dictionary, return-1
.
Example 1:
Input
["WordFilter", "f"]
[[["apple"]], ["a", "e"]]
Output
[null, 0]
Explanation
WordFilter wordFilter = new WordFilter(["apple"]);
wordFilter.f("a", "e"); // return 0, because the word at index 0 has prefix = "a" and suffix = 'e".
Constraints:
1 <= words.length <= 15000
1 <= words[i].length <= 10
1 <= prefix.length, suffix.length <= 10
words[i]
,prefix
andsuffix
consist of lower-case English letters only.- At most
15000
calls will be made to the functionf
.
题意
给定一个字符串数组,找到下标最大的字符串,使其前缀和后缀与给定值相同。
思路
字典树Trie应用。生成前缀树和后缀树,每次查询时,通过prefix找到所有满足条件的字符串,将其对应的下标加入到优先队列中,通过suffix进行相同操作,最后比较两个优先队列得到答案。
代码实现
Java
class WordFilter {
private Trie prefixT = new Trie(), suffixT = new Trie();
private Queue<Integer> prefixQ = new PriorityQueue<>(Comparator.reverseOrder());
private Queue<Integer> suffixQ = new PriorityQueue<>(Comparator.reverseOrder());
public WordFilter(String[] words) {
for (int i = 0; i < words.length; i++) {
insert(prefixT, words[i].toCharArray(), i);
insert(suffixT, new StringBuilder(words[i]).reverse().toString().toCharArray(), i);
}
}
public int f(String prefix, String suffix) {
prefixQ.clear();
suffixQ.clear();
search(prefixT, prefixQ, prefix);
search(suffixT, suffixQ, new StringBuilder(suffix).reverse().toString());
while (!prefixQ.isEmpty() && !suffixQ.isEmpty()) {
int a = prefixQ.peek(), b = suffixQ.peek();
if (a > b) prefixQ.poll();
else if (a < b) suffixQ.poll();
else return a;
}
return -1;
}
private void insert(Trie root, char[] word, int index) {
Trie cur = root;
for (char c : word) {
if (cur.next[c - 'a'] == null) cur.next[c - 'a'] = new Trie();
cur = cur.next[c - 'a'];
}
cur.end = true;
cur.index = index;
}
private void search(Trie root, Queue<Integer> pq, String part) {
for (char c : part.toCharArray()) {
if (root.next[c - 'a'] == null) return;
root = root.next[c - 'a'];
}
Queue<Trie> q = new LinkedList<>();
q.offer(root);
while (!q.isEmpty()) {
Trie cur = q.poll();
if (cur.end) pq.offer(cur.index);
for (int i = 0; i < 26; i++) {
if (cur.next[i] != null) q.offer(cur.next[i]);
}
}
}
class Trie {
Trie[] next = new Trie[26];
boolean end;
int index;
}
}