Design a special dictionary that searches the words in it by a prefix and a suffix.
Implement the WordFilter class:
WordFilter(string[] words) Initializes the object with the words in the dictionary.
f(string pref, string suff) Returns the index of the word in the dictionary, which has the prefix pref and the suffix suff. 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 <= 104
1 <= words[i].length <= 7
1 <= pref.length, suff.length <= 7
words[i], pref and suff consist of lowercase English letters only.
At most 104 calls will be made to the function f.
Solutions
Solution 1
1 2 3 4 5 6 7 8 9101112131415161718
classWordFilter:def__init__(self,words:List[str]):self.d={}fork,winenumerate(words):n=len(w)foriinrange(n+1):a=w[:i]forjinrange(n+1):b=w[j:]self.d[(a,b)]=kdeff(self,pref:str,suff:str)->int:returnself.d.get((pref,suff),-1)# Your WordFilter object will be instantiated and called as such:# obj = WordFilter(words)# param_1 = obj.f(pref,suff)
classWordFilter{privateMap<String,Integer>d=newHashMap<>();publicWordFilter(String[]words){for(intk=0;k<words.length;++k){Stringw=words[k];intn=w.length();for(inti=0;i<=n;++i){Stringa=w.substring(0,i);for(intj=0;j<=n;++j){Stringb=w.substring(j);d.put(a+"."+b,k);}}}}publicintf(Stringpref,Stringsuff){returnd.getOrDefault(pref+"."+suff,-1);}}/** * Your WordFilter object will be instantiated and called as such: * WordFilter obj = new WordFilter(words); * int param_1 = obj.f(pref,suff); */
classWordFilter{public:unordered_map<string,int>d;WordFilter(vector<string>&words){for(intk=0;k<words.size();++k){stringw=words[k];intn=w.size();for(inti=0;i<=n;++i){stringa=w.substr(0,i);for(intj=0;j<=n;++j){stringb=w.substr(j,n-j);d[a+"."+b]=k;}}}}intf(stringpref,stringsuff){stringkey=pref+"."+suff;if(d.count(key))returnd[key];return-1;}};/** * Your WordFilter object will be instantiated and called as such: * WordFilter* obj = new WordFilter(words); * int param_1 = obj->f(pref,suff); */
typeWordFilterstruct{dmap[string]int}funcConstructor(words[]string)WordFilter{d:=map[string]int{}fork,w:=rangewords{n:=len(w)fori:=0;i<=n;i++{a:=w[:i]forj:=0;j<=n;j++{b:=w[j:]d[a+"."+b]=k}}}returnWordFilter{d}}func(this*WordFilter)F(prefstring,suffstring)int{ifv,ok:=this.d[pref+"."+suff];ok{returnv}return-1}/** * Your WordFilter object will be instantiated and called as such: * obj := Constructor(words); * param_1 := obj.F(pref,suff); */
classTrie:def__init__(self):self.children=[None]*26self.indexes=[]definsert(self,word,i):node=selfforcinword:idx=ord(c)-ord("a")ifnode.children[idx]isNone:node.children[idx]=Trie()node=node.children[idx]node.indexes.append(i)defsearch(self,pref):node=selfforcinpref:idx=ord(c)-ord("a")ifnode.children[idx]isNone:return[]node=node.children[idx]returnnode.indexesclassWordFilter:def__init__(self,words:List[str]):self.p=Trie()self.s=Trie()fori,winenumerate(words):self.p.insert(w,i)self.s.insert(w[::-1],i)deff(self,pref:str,suff:str)->int:a=self.p.search(pref)b=self.s.search(suff[::-1])ifnotaornotb:return-1i,j=len(a)-1,len(b)-1while~iand~j:ifa[i]==b[j]:returna[i]ifa[i]>b[j]:i-=1else:j-=1return-1# Your WordFilter object will be instantiated and called as such:# obj = WordFilter(words)# param_1 = obj.f(pref,suff)
classTrie{Trie[]children=newTrie[26];List<Integer>indexes=newArrayList<>();voidinsert(Stringword,inti){Trienode=this;for(charc:word.toCharArray()){c-='a';if(node.children[c]==null){node.children[c]=newTrie();}node=node.children[c];node.indexes.add(i);}}List<Integer>search(Stringpref){Trienode=this;for(charc:pref.toCharArray()){c-='a';if(node.children[c]==null){returnCollections.emptyList();}node=node.children[c];}returnnode.indexes;}}classWordFilter{privateTriep=newTrie();privateTries=newTrie();publicWordFilter(String[]words){for(inti=0;i<words.length;++i){Stringw=words[i];p.insert(w,i);s.insert(newStringBuilder(w).reverse().toString(),i);}}publicintf(Stringpref,Stringsuff){suff=newStringBuilder(suff).reverse().toString();List<Integer>a=p.search(pref);List<Integer>b=s.search(suff);if(a.isEmpty()||b.isEmpty()){return-1;}inti=a.size()-1,j=b.size()-1;while(i>=0&&j>=0){intc=a.get(i),d=b.get(j);if(c==d){returnc;}if(c>d){--i;}else{--j;}}return-1;}}/** * Your WordFilter object will be instantiated and called as such: * WordFilter obj = new WordFilter(words); * int param_1 = obj.f(pref,suff); */
typeTriestruct{children[26]*Trieindexes[]int}funcnewTrie()*Trie{return&Trie{indexes:[]int{}}}func(this*Trie)insert(wordstring,iint){node:=thisfor_,c:=rangeword{idx:=c-'a'ifnode.children[idx]==nil{node.children[idx]=newTrie()}node=node.children[idx]node.indexes=append(node.indexes,i)}}func(this*Trie)search(prefstring)[]int{node:=thisfor_,c:=rangepref{idx:=c-'a'ifnode.children[idx]==nil{return[]int{}}node=node.children[idx]}returnnode.indexes}typeWordFilterstruct{p*Tries*Trie}funcConstructor(words[]string)WordFilter{p:=newTrie()s:=newTrie()fori,w:=rangewords{p.insert(w,i)s.insert(reverse(w),i)}returnWordFilter{p,s}}func(this*WordFilter)F(prefstring,suffstring)int{a:=this.p.search(pref)b:=this.s.search(reverse(suff))iflen(a)==0||len(b)==0{return-1}i,j:=len(a)-1,len(b)-1fori>=0&&j>=0{ifa[i]==b[j]{returna[i]}ifa[i]>b[j]{i--}else{j--}}return-1}funcreverse(wstring)string{ww:=[]byte(w)fori,j:=0,len(w)-1;i<j;i++{ww[i],ww[j]=ww[j],ww[i]j--}returnstring(ww)}/** * Your WordFilter object will be instantiated and called as such: * obj := Constructor(words); * param_1 := obj.F(pref,suff); */