Leetcode 745. Prefix and Suffix Search

Problem:

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:

  1. words has length in range [1, 15000].
  2. For each test case, up to words.length queries WordFilter.f may 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, suffix queries consist of lowercase letters only.

Solution:

  看到prefix和suffix,首先应该想到使用Trie这种数据结构的可能性,这道题涉及到后缀问题,所以我们需要设计一个函数rinsert来从单词最后一个字符开始创建Trie(insert函数和rinsert函数的差别仅仅在于遍历字符串的顺序相反而已)。因此tree是前缀树,rtree就成了后缀树。在TrieNode中,我还维护了一个last数组用于记录走过这个节点的索引值。我们通过访问一个TrieNode可以得到所有以该前缀在words中的索引号,即startWith的函数功能。所以,我们只需要所有出现过prefix的数组pre和所有出现过suffix的数组suf中找到同时出现且最大的索引号即可。

Code:

 

 1 struct TrieNode{
 2     TrieNode *next[26];
 3     bool isEnd;
 4     vector<int> last;
 5     TrieNode():isEnd(false),last(0){
 6         for(int i = 0;i != 26;++i)
 7             next[i] = NULL;
 8     }
 9 };
10 class TrieTree{
11 public:
12     TrieTree(){
13         root = new TrieNode();
14     }
15     void insert(string word,int index) {
16         TrieNode *current = root;
17         current->last.push_back(index);
18         for(int i = 0;i != word.size();++i){
19             if(current->next[word[i]-'a'] == NULL)
20                 current->next[word[i]-'a'] = new TrieNode();
21             current = current->next[word[i]-'a'];
22             current->last.push_back(index);
23         }
24         current->isEnd = true;
25     }
26     void rinsert(string word,int index) {
27         TrieNode *current = root;
28         current->last.push_back(index);
29         for(int i = word.size()-1;i >= 0;--i){
30             if(current->next[word[i]-'a'] == NULL)
31                 current->next[word[i]-'a'] = new TrieNode();
32             current = current->next[word[i]-'a'];
33             current->last.push_back(index);
34         }
35         current->isEnd = true;
36     }
37     vector<int> startWith(string prefix){
38         TrieNode *current = root;
39         for(int i = 0;i != prefix.size();++i){
40             if(current->next[prefix[i]-'a'] == NULL)
41                 return {};
42             current = current->next[prefix[i]-'a'];
43         }
44         return current->last;
45     }
46     struct TrieNode *getRoot(){
47         return root;
48     }
49 private:
50     TrieNode *root;
51 };
52 class WordFilter {
53 public:
54     WordFilter(vector<string> words) {
55         for(int i = 0;i != words.size();++i){
56             tree.insert(words[i],i);
57             rtree.rinsert(words[i],i);
58         }
59         
60     }
61     
62     int f(string prefix, string suffix) {
63         vector<int> pre = tree.startWith(prefix);
64         reverse(suffix.begin(),suffix.end());
65         vector<int> suf = rtree.startWith(suffix);
66         for(int i = pre.size()-1;i >= 0;--i){
67             for(int j = suf.size()-1;j >= 0;--j){
68                 if(pre[i] == suf[j]) 
69                     return pre[i];
70                 else if(pre[i] > suf[j])
71                     break;
72             }
73         }
74         return -1;
75     }
76 private:
77     TrieTree tree;
78     TrieTree rtree;
79 };
80 
81 /**
82  * Your WordFilter object will be instantiated and called as such:
83  * WordFilter obj = new WordFilter(words);
84  * int param_1 = obj.f(prefix,suffix);
85  */

 

posted on 2019-01-13 13:22  周浩炜  阅读(146)  评论(0编辑  收藏  举报

导航