滑动窗口

滑动窗口

问题描述

滑动窗口是一种在数组或字符串上使用双指针维护一个区间的技术。
通常,两个指针同向移动,通过动态更新区间内的信息来解决问题。

定长窗口

算法思想

  1. 维护固定大小的窗口
  2. 窗口右移时更新区间信息
  3. 适用于求解连续子数组的统计问题
  4. 时间复杂度

代码实现

class Solution {
public:
    vector<double> movingAverage(vector<int>& nums, int k) {
        vector<double> result;
        int n = nums.size();
        if (n < k) return result;
        
        // 初始化第一个窗口
        double sum = 0;
        for (int i = 0; i < k; i++) {
            sum += nums[i];
        }
        result.push_back(sum / k);
        
        // 窗口滑动
        for (int i = k; i < n; i++) {
            sum = sum - nums[i-k] + nums[i];
            result.push_back(sum / k);
        }
        
        return result;
    }
};
class Solution {
    public double[] movingAverage(int[] nums, int k) {
        int n = nums.length;
        if (n < k) return new double[0];
        
        double[] result = new double[n - k + 1];
        
        // 初始化第一个窗口
        double sum = 0;
        for (int i = 0; i < k; i++) {
            sum += nums[i];
        }
        result[0] = sum / k;
        
        // 窗口滑动
        for (int i = k; i < n; i++) {
            sum = sum - nums[i-k] + nums[i];
            result[i-k+1] = sum / k;
        }
        
        return result;
    }
}
class Solution:
    def movingAverage(self, nums: List[int], k: int) -> List[float]:
        n = len(nums)
        if n < k:
            return []
        
        # 初始化第一个窗口
        window_sum = sum(nums[:k])
        result = [window_sum / k]
        
        # 窗口滑动
        for i in range(k, n):
            window_sum = window_sum - nums[i-k] + nums[i]
            result.append(window_sum / k)
        
        return result

不定长窗口

算法思想

  1. 使用双指针维护满足条件的窗口
  2. 右指针扩展窗口,左指针收缩窗口
  3. 动态维护窗口内的状态信息
  4. 更新最优解

代码实现

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        vector<int> count(128, 0);  // 字符计数
        int maxLen = 0;
        int left = 0, right = 0;
        
        while (right < s.length()) {
            count[s[right]]++;
            
            // 出现重复字符时收缩窗口
            while (count[s[right]] > 1) {
                count[s[left]]--;
                left++;
            }
            
            maxLen = max(maxLen, right - left + 1);
            right++;
        }
        
        return maxLen;
    }
};
class Solution {
    public int lengthOfLongestSubstring(String s) {
        int[] count = new int[128];  // 字符计数
        int maxLen = 0;
        int left = 0, right = 0;
        
        while (right < s.length()) {
            count[s.charAt(right)]++;
            
            // 出现重复字符时收缩窗口
            while (count[s.charAt(right)] > 1) {
                count[s.charAt(left)]--;
                left++;
            }
            
            maxLen = Math.max(maxLen, right - left + 1);
            right++;
        }
        
        return maxLen;
    }
}
class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        char_count = {}  # 字符计数
        max_len = left = 0
        
        for right, char in enumerate(s):
            char_count[char] = char_count.get(char, 0) + 1
            
            # 出现重复字符时收缩窗口
            while char_count[char] > 1:
                char_count[s[left]] -= 1
                left += 1
            
            max_len = max(max_len, right - left + 1)
        
        return max_len

时间复杂度分析

算法 时间复杂度 空间复杂度
定长窗口
不定长窗口
多指针窗口
计数窗口

应用场景

  1. 子数组的统计
  2. 子串的匹配
  3. 连续序列问题
  4. 数据流的处理
  5. 固定窗口的计算

注意事项

  1. 窗口大小的选择
  2. 窗口状态的维护
  3. 边界条件的处理
  4. 窗口移动的条件
  5. 最优解的更新时机

经典例题

  1. 小红的01子序列构造
  2. 而后单调
  3. 相差不超过k的最多数
  4. 请客吃饭
牛客代码笔记-牛栋 文章被收录于专栏

汗牛充栋,学海无涯。<br/> 内含算法知识点讲解,以及牛客题库精选例题。<br/> 学习算法,从牛栋开始。

全部评论

相关推荐

来,说点可能被同行“骂”的大实话。🙊当初接数字马力Offer时,朋友都说:“蚂蚁的“内包”公司?你想清楚啊!”但入职快一年后的今天,我反而对他有了不一样的看法!🔹&nbsp;是偏见?还是信息差!之前没入职之前外面都在说什么岗位低人一等这类。实际上:这种情况不可至否,不能保证每个团队都是其乐融融。但我在的部门以及我了解的周边同事都还是十分好相处的~和蚂蚁师兄师姐之间也经常开一些小玩笑。总之:身份是蚂蚁公司给的,地位是自己挣的(一个傲娇女孩的自述)。🔹&nbsp;待遇?玩的就是真实!试用期工资全额发!六点下班跑得快(早9晚6或者早10晚7,动态打卡),公积金顶格交。别听那些画饼的,到手的钱和下班的时间才是真的(都是牛马何必难为牛马)。🔹&nbsp;能不能学到技术?来了就“后悔”!我们拥有权限直通蚂蚁知识库,技术栈多到学不完。说“学不到东西”的人,来了可能后悔——后悔来晚了(哈哈哈哈,可以不学但是不能没有)!💥&nbsp;内推地址:https://app.mokahr.com/su/ueoyhg❗我的内推码:NTA6Nvs走我的内推,可以直达业务部门,面试流程更快速,进度可查!今天新放HC,之前挂过也能再战!秋招已经正式开始啦~机会就摆在这,敢不敢来试一试呢?(和我一样,做个勇敢的女孩)
下午吃泡馍:数字马力的薪资一般哇,5年经验的java/测试就给人一万出头,而且刚入职第三天就让人出差,而且是出半年
帮你内推|数字马力 校招
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务