【Day 3】公开打卡第3天 | LeetCode 438. 找到字符串中所有字母异位词 + Go 滑动窗口模板
正文结构:
-
今日打卡宣言 Day 3,继续坚持!昨天做了最长回文子串,今天换一道滑动窗口高频题。项目忙归忙,但回家后还是挤出时间手写了一遍。连续3天没断,感觉越来越有动力了,欢迎继续监督!
-
LeetCode 部分
- 题目链接:leetcode.cn/problems/fi…
- 难度:中等
- 时间复杂度:O(n)(n = s 长度)
- 核心思路(简短3行): 用固定长度窗口(等于 p 的长度)在 s 上滑动。维护两个计数器(p 的字符频次 + 当前窗口频次)。当窗口频次完全匹配 p 时,记录起始索引。滑动时只更新移出/移入的字符,高效 O(26) 判断匹配。
- 代码(Go 版本,标准滑动窗口 + 数组计数器,更快):
Go
func findAnagrams(s string, p string) []int {
if len(p) > len(s) {
return []int{}
}
var pCount [26]int
var winCount [26]int
for _, ch := range p {
pCount[ch-'a']++
}
var result []int
// 初始化第一个窗口
for i := 0; i < len(p); i++ {
winCount[s[i]-'a']++
}
if winCount == pCount {
result = append(result, 0)
}
// 滑动窗口
for i := len(p); i < len(s); i++ {
// 移出左边字符
winCount[s[i-len(p)]-'a']--
// 移入右边字符
winCount[s[i]-'a']++
if winCount == pCount {
result = append(result, i-len(p)+1)
}
}
return result
}
- C++ 版本:
C++
class Solution {
public:
vector<int> findAnagrams(string s, string p) {
if (p.size() > s.size()) return {};
// 相当于是, 固定滑窗, 并且判断窗口内是否相同
vector<int> res;
array<int, 26> pCnt = {}; array<int, 26>windowCnt = {};
// 先初始化第0个
for (char c : p) pCnt[c - 'a'] ++;
for (int i = 0; i < p.size(); i++)
{
windowCnt[s[i] - 'a'] ++;
}
if (pCnt == windowCnt) {
res.emplace_back(0);
}
// 接之后的窗口
for (int i = p.size(); i < s.size(); i++)
{
// 左边的移出来
windowCnt[s[i - p.size()] - 'a']--;
// 当前的加进来
windowCnt[s[i] - 'a'] ++;
if (windowCnt == pCnt)
{
res.emplace_back(i - p.size() + 1);
}
}
return res;
}
};
-
易错点/优化点:
- 窗口长度必须固定为 len(p),别用可变窗口。
- 用 [26]int 数组比 map 快得多(因为小写字母限定)。
- 数组直接 == 比较(Go/C++ 支持),不用每次循环26个。
- 面试追问:如果字符集更大?(用 map,但 O(n log 26) 变 O(n * 26))。示例:s = "cbaebabacd", p = "abc" → [0,6]
-
知识点部分(Go 滑动窗口通用模板 & 数组 vs map) Go 滑动窗口模板 & 计数器选择
-
固定窗口模板(这题典型):先初始化窗口 → 判断 → 然后 while 右指针移动,更新,判断,必要时移动左指针。
-
为什么用 [26]int 而不是 map[string]int?
- 数组访问 O(1),map 有 hash 开销 + 内存更大。
- 小写字母限定时,数组碾压 map(性能 + 代码简洁)。
-
面试常问:什么时候用 map?(字符集不确定或 unicode 时)。
-
扩展:可变窗口(Day 1 的无重复子串),用 map + left 指针移动。
-
-
今日感悟 这道题是滑动窗口的经典应用,以前只刷过无重复子串那种可变窗口,今天固定窗口 + 数组计数器写出来才发现更高效。公开打卡让我必须把边界和优化点都搞清楚,不然发出去自己都心虚。Day 3 了,越来越觉得这个习惯在改变我。继续!
-
结束语 明天见! 欢迎评论区交流:① 你的滑动窗口模板怎么写 ② 代码哪里还能优化 ③ 你最近刷到的好题推荐 #程序员打卡 #LeetCode #Go语言 #滑动窗口 #字母异位词