Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Range ...
- type Range struct {
- begin, end int
- }
- // Fragment ...
- type Fragment struct {
- substr []rune
- rng Range
- charset map[rune]bool
- }
- // Len ...
- func (f *Fragment) Len() int {
- return f.rng.end - f.rng.begin
- }
- func toString(m map[rune]bool) string {
- ret := []rune{}
- for r := range m {
- ret = append(ret, r)
- }
- return string(ret)
- }
- // SoFar ...
- type SoFar struct {
- fragments []*Fragment
- maxFragmentLen int
- }
- func (sf *SoFar) condAdd(f *Fragment) {
- if f.Len() <= sf.maxFragmentLen {
- return
- }
- sf.fragments = append(sf.fragments, f)
- sf.maxFragmentLen = f.Len()
- }
- func (sf *SoFar) uncondAdd(f *Fragment) {
- sf.fragments = append(sf.fragments, f)
- if f.Len() >= sf.maxFragmentLen {
- sf.maxFragmentLen = f.Len()
- }
- }
- func toChars(s string) []rune {
- ret := []rune{}
- for _, ch := range s {
- ret = append(ret, ch)
- }
- return ret
- }
- func solveImpl(offset int, chars []rune) SoFar {
- output := SoFar{}
- if offset == len(chars) {
- return output
- }
- ch := chars[offset]
- output.uncondAdd(&Fragment{
- substr: []rune{ch},
- rng: Range{begin: offset, end: offset + 1},
- charset: map[rune]bool{ch: true},
- })
- soFar := solveImpl(offset+1, chars)
- for _, fragm := range soFar.fragments {
- // check if there's a gap between the current rune ch and the fragm
- if fragm.rng.begin-offset > 1 {
- output.condAdd(fragm)
- continue
- }
- // if current char exists in the fragment
- if fragm.charset[ch] {
- output.condAdd(fragm)
- continue
- }
- head := []rune{ch}
- fragm.charset[ch] = true
- output.uncondAdd(&Fragment{
- substr: append(head, fragm.substr...),
- rng: Range{begin: offset, end: fragm.rng.end},
- charset: fragm.charset,
- })
- }
- maxFragmLen := 0
- for _, f := range output.fragments {
- if f.Len() >= maxFragmLen {
- maxFragmLen = f.Len()
- }
- }
- output.maxFragmentLen = maxFragmLen
- return output
- }
- func solve(s string) int {
- chars := toChars(s)
- soFar := solveImpl(0, chars)
- if len(soFar.fragments) < 1 {
- return 0
- }
- m := 0
- maxFragmentIdx := 0
- for i, f := range soFar.fragments {
- if f.Len() > m {
- maxFragmentIdx = i
- }
- }
- return soFar.fragments[maxFragmentIdx].Len()
- }
- func lengthOfLongestSubstring(s string) int {
- return solve(s)
- }
Advertisement
Add Comment
Please, Sign In to add comment