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

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. 边界情况如何处理?

相关推荐
Nil20827 分钟前
leetcode 160相交链表
算法·leetcode·链表
迷途之人不知返1 小时前
算法系列2:滑动窗口
算法
Herbert_hwt2 小时前
C语言零基础入门:循环控制与数据类型详解
c语言·数据结构·算法
Tisfy3 小时前
LeetCode 3090.每个字符最多出现两次的最长子字符串:二重循环 / 滑动窗口
算法·leetcode·字符串·题解·模拟·双指针·滑动窗口
-dzk-3 小时前
【技巧】LC 136.只出现一次的数字
算法·异或
有点。3 小时前
C++二叉树二(练习题)
数据结构·c++·算法·图论
专注仿真4 小时前
问答大模型技术方案算法实现-RAPTOR树构建算法与BEG集成使用
python·算法
zlinear数据采集卡5 小时前
数据采集卡从入门到精通(10):采样率与分辨率的核心关系——反比律、架构分布与过采样
arm开发·嵌入式硬件·算法·fpga开发·架构·开源
GeekZHR6 小时前
C语言指针进阶补充6:动态内存管理、mem系列内存函数、复杂指针声明,一次补齐指针的“三大盲区“
java·c语言·算法·指针
Herbert_hwt6 小时前
第七章 Java深入理解枚举类型
java·开发语言·算法