745. 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:

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 1 : build two tries , suffix and prefix trie (TLE)
Every node has a list of weight 
When search for words with prefix and suffix , traverse these two tries and get the intersection of these two sets , return the smallest weight 



/**
 * Your WordFilter object will be instantiated and called as such:
 * WordFilter obj = new WordFilter(words);
 * int param_1 = obj.f(prefix,suffix);
 */


class WordFilter {
    TrieNode trie1, trie2;
    public WordFilter(String[] words) {
        trie1 = new TrieNode();
        trie2 = new TrieNode();
        int wt = 0;
        for (String word: words) {
            char[] ca = word.toCharArray();

            TrieNode cur = trie1;
            cur.weight.add(wt);
            for (char letter: ca) {
                if (cur.children[letter - 'a'] == null)
                    cur.children[letter - 'a'] = new TrieNode();
                cur = cur.children[letter - 'a'];
                cur.weight.add(wt);
            }

            cur = trie2;
            cur.weight.add(wt);
            for (int j = ca.length - 1; j >= 0; --j) {
                char letter = ca[j];
                if (cur.children[letter - 'a'] == null)
                    cur.children[letter - 'a'] = new TrieNode();
                cur = cur.children[letter - 'a'];
                cur.weight.add(wt);
            }
            wt++;
        }
    }

    public int f(String prefix, String suffix) {
        TrieNode cur1 = trie1, cur2 = trie2;
        for (char letter: prefix.toCharArray()) {
            if (cur1.children[letter - 'a'] == null) return -1;
            cur1 = cur1.children[letter - 'a'];
        }
        char[] ca = suffix.toCharArray();
        for (int j = ca.length - 1; j >= 0; --j) {
            char letter = ca[j];
            if (cur2.children[letter - 'a'] == null) return -1;
            cur2 = cur2.children[letter - 'a'];
        }

        int ans = -1;
        for (int w1: cur1.weight)
            if (w1 > ans && cur2.weight.contains(w1))
                ans = w1;

        return ans;
    }
}

class TrieNode {
    TrieNode[] children;
    Set<Integer> weight;
    public TrieNode() {
        children = new TrieNode[26];
        weight = new HashSet();
    }
}










Solution 2 : 
 Trie of Suffix Wrapped Words 
Intuition and Algorithm
Consider the word 'apple'. For each suffix of the word, we could insert that suffix, followed by '#', followed by the word, all into the trie.
For example, we will insert '#apple', 'e#apple', 'le#apple', 'ple#apple', 'pple#apple', 'apple#apple' into the trie. Then for a query like prefix = "ap", suffix = "le", we can find it by querying our trie for le#ap.



Solution 3 : 
Use hash map , store all possible prefix suffix pair, so when there is an incoming word, just search for it in HashMap, O(1) look up 


{ is right after z in ascii code 
https://www.google.com/search?q=ascii+code&num=100&rlz=1C5CHFA_enUS766US767&source=lnms&tbm=isch&sa=X&ved=0ahUKEwiunNf1hPPdAhWJiFQKHUf_DJcQ_AUIDigB&biw=1198&bih=722#imgrc=8TZS0UxreQ2XgM:






    
class WordFilter{
    TrieNode trie;
    public WordFilter(String[] words){
        trie = new TrieNode();
        for(int weight = 0; weight < words.length; weight++){
            String word = words[weight] + "{";
            for(int i = 0; i < word.length(); i++){
                TrieNode cur = trie;
                cur.weight = weight;
                for(int j = i; j < 2 * word.length() * 2 - 1; j++){
                    int k = word.charAt(j % word.length()) - 'a';
                    if(cur.children[k] == null){
                        cur.children[k] = new TrieNode();
                    }
                    cur = cur.children[k];
                    cur.weight = weight;
                }
            }
        }
    }
    public int f(String prefix, String suffix){
        TrieNode cur = trie;
        for(char letter : (suffix + '{' + prefix).toCharArray()){
            if(cur.children[letter - 'a'] == null) return -1;
            cur = cur.children[letter - 'a'];
        }
        return cur.weight;
    }
}

class TrieNode {
    TrieNode[] children;
    int weight;
    public TrieNode() {
        children = new TrieNode[27];
        weight = 0;
    }
}





https://www.youtube.com/watch?v=a-4WbFqalIA

https://leetcode.com/problems/prefix-and-suffix-search/solution/

 

posted on 2018-11-06 10:10  猪猪&#128055;  阅读(164)  评论(0)    收藏  举报

导航