滑动窗口解题技巧

本文介绍了滑动窗口在解决编程问题中的应用,通过LeetCode的三个题目——和为s的连续正数序列、滑动窗口最大值和最长不含重复字符的字符串,详细讲解了滑动窗口技巧的实现思路和优化方法,包括使用双端队列来维护窗口最大值以及如何查找字母异位词。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.和为s的连续正数序列

在这里插入图片描述

class Solution {
public:
    vector<vector<int>> findContinuousSequence(int target) {
        int left = 1;
        int right = 1;
        int sum = 0;
        vector<vector<int>> res;
        while (left <= target / 2 + 1){
            if (sum < target){
                sum+=right;
                right++;
            }
            else if (sum > target) {
                sum-=left;
                left++;
            }
            else {
                vector<int> vec;
                for(int k = left; k <right; k++){
                    vec.push_back(k);  
                }
                 res.push_back(vec);
                 sum-=left;
                 left++;
            }
        }
        return res;

    }
};

2.LeetCode239.滑动窗口的最大值

在这里插入图片描述

本题我们维护一个双端队列,每次对要进来的元素进行判断,确保双端队列从队头到队尾是从大到小,队头存放当前窗口的最大值,为了确保是当前窗口最大值,就需要对队头进行判断。deq.front() == nums[i-k]就是检查是不是当前窗口。

在这里插入图片描述

class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        vector<int> res;
        deque<int> deq;
        int len = nums.size();

        for(int i = 0; i < len; i++){
            while (!deq.empty() && deq.back() < nums[i]) deq.pop_back();
            if (!deq.empty() && i >= k && deq.front() == nums[i-k]) deq.pop_front();
                 deq.push_back(nums[i]);

            if (i >= k-1) res.push_back(deq.front());
        }
        return res;
    }
};

2.LeetCode3.最长不含重复字符的字符串

在这里插入图片描述
C++(自己思路)

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        if (s.size() == 0) return 0;
        int Max = INT_MIN;
        int size = s.size();
        set<char> set;
        deque<char> deq;

        for (int i = 0; i < size; i++) {
           if (set.insert(s[i]).second) {
               deq.push_back(s[i]);
               if(i == size-1) Max = max((int)deq.size(), Max);
           }
           else{
               Max = max((int)deq.size(), Max); 
               while (!deq.empty()) {
                   set.erase(deq.front());
                   deq.pop_front();
                   if(set.insert(s[i]).second) {
                       deq.push_back(s[i]);
                       break;
                   }
               }
           }
        }
        return Max;


    }
};

C++(题解)

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        map<char,int> map;
        int size = s.size();
        int result=0;
        for (int left = 0, right = 0; right < size; right++) {
            if(map.find(s[right])!=map.end()) {
                left =max(map[s[right]]+1, left);
            }
            result = max(result, right - left + 1);
            map[s[right]] = right;
        }
        return result;

    }
};

C++终极简化版:

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int arr[256]={0};
        int size = s.size();
        int result=0;
        for (int left = 0, right = 0; right < size; right++) {
           char c=s[right];
           left=max(arr[c],left);
           result=max(result,right-left+1);
           arr[c]=right+1;
        }
        return result;
    }
};                                                                    

3.LeetCode438.找到字符串中所有字母异位词

在这里插入图片描述

class Solution {
public:
    vector<int> findAnagrams(string s, string p) {
        int sSize = (int)s.size();
        int pSize = (int)p.size();
        if(sSize < pSize) return {};
        
        vector<int> rs;
        vector<int> needs(26,0);  //p
        vector<int> window(26,0); //s
        for (char c : p) needs[c - 'a']++;
        
        int left = 0, right = 0;
        while (right < sSize) {
            char charR = s[right++];
            window[charR - 'a']++;
            while (window[charR - 'a'] > needs[charR - 'a']) {
                char charL = s[left];
                window[charL - 'a']--;
                left++;
            }
            if (right - left == pSize) {
                rs.push_back(left);
            }
        }
        return rs;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值