068_找到字符串中所有字母异位词

知识点:滑动窗口、数组

LeetCode第四百三十八题:https://leetcode-cn.com/problems/find-all-anagrams-in-a-string/submissions/

语言:GoLang

// 滑动窗口,仅仅是将map改成[26]int,时间就从44%变成100%,相差这么大的吗
func findAnagrams(s string, p string) []int {
    sLen, pLen := len(s), len(p)

    setLen := 0
    sets := [26]int{}
    for i := 0; i < pLen; i++ {
        if sets[p[i] - 'a'] == 0 {
            setLen++
        }
        sets[p[i] - 'a']++
    }

    result := []int{}
    left, right, counter, window := 0, 0, 0, [26]int{}
    for left < sLen - pLen + 1 {
        rc := s[right] - 'a'
        right++

        // 跳过不必要的元素
        if sets[rc] == 0 && counter > 0 {
            left, counter, window = right, 0, [26]int{}
            continue
        }

        window[rc]++
        if window[rc] == sets[rc] {
            counter++
        }

        for right - left >= pLen {
            if counter == setLen {
                result = append(result, left)
            }

            lc := s[left] - 'a'
            left++
            if window[lc] == sets[lc] {
                counter--
            }
            window[lc]--
        }
    }

    return result
}



// 滑动窗口,map版本
func findAnagrams_0(s string, p string) []int {
    sLen, pLen := len(s), len(p)

    sets := map[byte]int{}
    for i := 0; i < pLen; i++ {
        sets[p[i]]++
    }

    result := []int{}
    left, right, counter, window := 0, 0, 0, map[byte]int{}
    for right < sLen {
        rc := s[right]
        right++

        if sets[rc] == 0 {
            left, counter, window = right, 0, map[byte]int{}
            continue
        }

        if sets[rc] > 0 {
            window[rc]++
            if window[rc] == sets[rc] {
                counter++
            }
        }

        for right - left >= pLen {
            if counter == len(sets) {
                result = append(result, left)
            }

            lc := s[left]
            left++
            if sets[lc] > 0 {
                if window[lc] == sets[lc] {
                    counter--
                }
                window[lc]--
            }
        }
    }

    return result
}





// 朴素解法,O(m*n),m,n分别为s和p的长度
func findAnagrams_(s string, p string) []int {
    sLen, pLen := len(s), len(p)

    result := []int{}
    for i := 0; i < sLen - pLen + 1; i++ {
        if isSame(s[i : i + pLen], p) {
            result = append(result, i)
        }
    }

    return result
}

func isSame(s1, s2 string) bool {
    length := len(s1)
    container := [26]int{}

    for i := 0; i < length; i++ {
        container[s1[i] - 'a']++
        container[s2[i] - 'a']--
    }

    for i := 0; i < 26; i++ {
        if container[i] != 0 {
            return false
        }
    }

    return true
}
posted @ 2020-07-16 17:40  Cenyol  阅读(88)  评论(0编辑  收藏  举报