funcfindAnagrams(s string, p string) []int { // 先判断特殊情况 iflen(s) == 1 && len(p) == 1 { if s == p { return []int{0} } else { return []int{} } }
pLen := len(p) pMap := make(map[rune]int)
res := make([]int, 0) for _, v := range p { pMap[v]++ }
for i := 0; i+pLen <= len(s); i++ { tmpMap := make(map[rune]int) tmpStr := s[i : i+pLen] for _, v := range tmpStr { tmpMap[v]++ } flag := false for k, v := range pMap { if tmpMap[k] != v { flag = false break } else { flag = true continue } } if flag { res = append(res, i) } } return res }
funcfindAnagrams(s string, p string) []int { sLen, pLen := len(s), len(p) if sLen < pLen { return []int{} } if sLen == pLen && pLen == 1 { if s == p { return []int{0} } else { return []int{} } } //先处理特殊情况
sCount, pCount := [26]int{}, [26]int{} //sCount: s的滑动窗口中每个字符出现的次数 //pCount: p中每个字符出现的次数 for i, v := range p { sCount[s[i]-'a']++ pCount[v-'a']++ //分别统计两个数组对应字母数量 //因为用的"-'a'",自然是按字母表顺序的 }
res := make([]int, 0) // 初始化答案数组 // 尝试首次匹配 if sCount == pCount { res = append(res, 0) }
for i, v := range s[:sLen-pLen] { // 开始遍历 因要有pLen长度在,故只需滑起点在[0,sLen-pLen)空间 sCount[v-'a']-- // 减去离开窗口的当前字母 sCount[s[i+pLen]-'a']++ // 加上新进入窗口的下一字母 if sCount == pCount { res = append(res, i+1) } }