leet-code/prefix-and-suffix-search/sol.go

110 lines
2.1 KiB
Go

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);
*/