滑动窗口的典例以及思路阐述

3. 无重复字符的最长子串 - 力扣(LeetCode)

438. 找到字符串中所有字母异位词 - 力扣(LeetCode)

在写这两道题的时候,我觉得使用滑动窗口的思路会比较清晰,虽然这两题具体解法有差异,但是思考方式类似:

解法核心思想:

  1. 计数映射:用哈希表记录p中每个字符应该出现的次数

  2. 滑动验证:在s上滑动窗口,通过计数正负判断字符匹配情况

  3. 动态调整:当某个字符"超标"时,收缩左边界直到恢复正常

对于异位词这题具体说明一下滑窗的思考逻辑:

1. 确定窗口含义

  • 固定窗口:窗口大小固定(如本题窗口大小固定为p的长度)

  • 可变窗口:窗口大小根据条件变化(如前一个无重复字符问题)

2. 定义窗口状态

cpp 复制代码
// 通常需要维护的状态
unordered_map<char, int> window;  // 窗口内字符计数
int left = 0;                     // 窗口左边界

3. 明确扩展和收缩条件

cpp 复制代码
for (int right = 0; right < s.size(); right++) {
    // 1. 右指针扩展,更新窗口状态
    window[s[right]]++;
    
    // 2. 判断是否需要收缩左边界
    while (需要收缩的条件) {
        // 更新左边界对应的状态
        window[s[left]]--;
        left++;
    }
    
    // 3. 检查是否满足题目要求
    if (满足条件) {
        // 记录答案
    }
}

完整题解代码:

cpp 复制代码
class Solution {
public:
    vector<int> findAnagrams(string s, string p) {
        vector<int> res;
        unordered_map<char,int> cnt;  // 记录p中字符出现次数
        int s_len = s.size();
        int p_len = p.size();
        if(s_len < p_len) return {};  // 边界情况处理

        // 初始化p的字符计数
        for(char ch : p){
            cnt[ch]++;
        }

        int left = 0;
        for(int right = 0; right < s_len; right++){
            cnt[s[right]]--;  // 右指针扩展,对应字符计数减1
            
            // 关键:当某个字符计数为负,说明当前窗口包含过多该字符
            while(cnt[s[right]] < 0){
                cnt[s[left]]++;  // 左指针收缩,恢复字符计数
                left++;
            }
            
            // 窗口大小等于p长度时,找到异位词
            if(right - left + 1 == p_len){
                res.push_back(left);
            }
        }
        return res;
    }
};

在遇到滑动窗口问题时,我觉得可以从以下几个方面去思考:

  1. 窗口大小是固定还是可变的?

  2. 需要记录哪些窗口状态?(字符计数、和、乘积等)

  3. 右指针扩展时如何更新状态?

  4. 什么条件下需要收缩左边界?

  5. 如何判断当前窗口是否满足要求?

  6. 边界情况如何处理?

相关推荐
通信小呆呆9 小时前
当算法有了“五感”:多模态数据融合如何向人体感官协同学习?
人工智能·学习·算法·机器学习·机器人
benben0449 小时前
强化学习之DQN算法族(基于gymnasium开发)
算法
何以解忧,唯有..11 小时前
Go语言循环语句详解:for、range与循环控制
开发语言·算法·golang
想吃火锅100511 小时前
【leetcode】88.合并两个有序数组js
算法
生成论实验室12 小时前
机器人:一个自主运动的系统
人工智能·算法·语言模型·机器人·自动驾驶·agi·安全架构
Qres82112 小时前
算法复键——树状数组
数据结构·算法
H1785350909612 小时前
SolidWorks第四部分_直接实体建模特征9_替换面原理
线性代数·算法·机器学习·3d建模·solidworks
不会就选b12 小时前
算法日常・每日刷题--<二分查找>3
算法
绿算技术13 小时前
Mooncake 与绿算ForinnBase GroundPool如何联手打破推理僵局?
科技·算法·架构