package main type StringMap struct { Map SubStringMap } func NewStringMap() *StringMap { return &StringMap{ Map: map[byte]*StringMap{}, } } func (sm *StringMap) CombineAllSubStrings(prefix string, rev bool) []string { if len(sm.Map) == 0 { return []string{prefix} } out := []string{} for chr, Map := range sm.Map { if rev { out = append(out, Map.CombineAllSubStrings(string(chr)+prefix, rev)...) } else { out = append(out, Map.CombineAllSubStrings(prefix+string(chr), rev)...) } } return out } func (sm *StringMap) Add(word string, rev bool) { if len(word) == 0 { return } take := 0 if rev { take = len(word) - 1 } sub, ok := sm.Map[word[take]] if !ok { sub = NewStringMap() sm.Map[word[take]] = sub } if rev { sub.Add(word[:take], rev) } else { sub.Add(word[1:], rev) } } type SubStringMap = map[byte]*StringMap type WordFilter struct { Prefixes *StringMap Suffixes *StringMap Words map[string]int } func Constructor(words []string) WordFilter { Prefixes := NewStringMap() Suffixes := NewStringMap() Words := map[string]int{} for idx, word := range words { Words[word] = idx Prefixes.Add(word, false) Suffixes.Add(word, true) } return WordFilter{ Prefixes: Prefixes, Suffixes: Suffixes, Words: Words, } } func (wf *WordFilter) F(prefix, suffix string) int { prefix_base, ok := wf.Prefixes, true for i := range prefix { prefix_base, ok = prefix_base.Map[prefix[i]] if !ok { return -1 } } suffix_base := wf.Suffixes for i := len(suffix) - 1; i >= 0; i-- { suffix_base, ok = suffix_base.Map[suffix[i]] if !ok { return -1 } } prefix_found := map[string]bool{} for _, found := range prefix_base.CombineAllSubStrings(prefix, false) { prefix_found[found] = true } max := -1 for _, found := range suffix_base.CombineAllSubStrings(suffix, true) { if _, ok := prefix_found[found]; ok { idx := wf.Words[found] if idx > max { max = idx } } } return max } /** * Your WordFilter object will be instantiated and called as such: * obj := Constructor(words); * param_1 := obj.F(prefix,suffix); */