438. 找到字符串中所有字母的异位词
题目描述
给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。
输入输出示例及数据范围
思路
这道题的思路其实很简单,就是一个滑动窗口的裸题,但是 LeetCode 官方题解当中给出的 Golang 解法非常适合学习,因此通过本篇文章进行记录。
具体来说,Golang 与 C++ 不同,Golang 的 slice 不能比较,因为 slice 是引用类型,而 C++ 的 vector 之间可以相互比较。但 Golang 的数组之间可以相等比较,前提是数组的类型完全相同【需要注意的是,数组的长度也是数组类型的一部分】。
解决这道题要使用数组来完成。具体来说,我们开两个长度为 26 的整型数组,用于存储子串中字符的个数。我们需要用 s 串的子串来匹配 p 串,如果 p 的长度在开始时就大于 s,那么答案为空。否则我们先记录 p 串的长度。题解当中同时统计 p 串和 s 串从 0 开始到 len(p) - 1
区间内的字符个数,如果二者匹配,则 0 是答案的一部分,代表从 0 开始的 s 子串与 p 匹配。
之后,官方题解用到了数组的切片,这一点我一开始确实没想到。在 for loop 中从 0 遍历到 len(s) - len(p) - 1
,然后统计 i + 1
到 i + len(p) + 1
这个区间内 s 子串的字符个数。统计完成后,再与 p 串比较,如果两个数组相等,则模式匹配成功,记录 i + 1
作为答案的一部分即可。
Golang 代码
func findAnagrams(s string, p string) []int {ans := []int{}if len(s) < len(p) {return ans}ms, mp := [26]int{}, [26]int{}for i, ch := range(p) {ms[s[i] - 'a'] ++mp[ch - 'a'] ++}if ms == mp {ans = append(ans, 0)}for i, ch := range(s[:len(s) - len(p)]) {ms[ch - 'a'] --ms[s[i + len(p)] - 'a'] ++if ms == mp {ans = append(ans, i + 1)}}return ans
}