力扣滑动窗口

本文探讨了五个与字符串、数组操作相关的算法问题:寻找最短长度的子数组、水果分配、最小覆盖子串、字符串排列匹配和异位词查找。解决方案涉及窗口滑动、哈希映射和动态调整,展示了如何在不同场景下实现高效算法设计。
摘要由CSDN通过智能技术生成

有框架

设置头部和尾部
for(移动尾部直到最后){
	更新窗口值
	while(当窗口值刚符合条件或刚不符合条件){
		移动头部直到符合条件或刚不符合条件
		记录窗口值和结果
	}
}

209.长度最小的子数组

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        unordered_map<int,int> window;
        int left = 0,right = 0;
        int res = INT_MAX;
        int cnt = 0;
        while(right < nums.size()){
            cnt += nums[right];
            while(cnt >= target){
                res = min(res,right - left + 1);
                int tmp = nums[left];
                left++;
                cnt -= tmp;
            }
            right++;
        }
        return res == INT_MAX?0:res;
    }
};

904. 水果成篮
这里与上面不同的地方在于,上面的过程是一开始不符合条件,头部一直动直到符合条件,是需要得到刚>=target的窗口,因此移动头部直到符合;下面是一开始就符合条件,只是需要得到最大符合条件的窗口,所以需要得到刚破坏条件的时候

因此导致了判断条件不同

class Solution {
public:
    int totalFruit(vector<int>& fruits) {
        unordered_map<int,int> window;
        int need = 2;
        int left = 0,right = 0;
        int res = 0;
        while(right < fruits.size()){
            int tmp = fruits[right];
            window[tmp]++;
            while(window.size() > need){
                int tmp = fruits[left];
                left++;
                window[tmp]--;
                if(window[tmp] == 0)window.erase(tmp);
            }
            res = max(res,right - left + 1);
            right++;
        }
        return res;
    }
};

76. 最小覆盖子串

class Solution {
public:
    string minWindow(string s, string t) {
        unordered_map<char,int> window,need;
        for(auto c:t)need[c]++;
        int left = 0,right = 0;
        int valid = 0;
        int len = INT_MAX;
        int start = 0;
        while(right < s.size()){
            char c = s[right];
            if(need.find(c) != need.end()){
                window[c]++;
                if(window[c] == need[c]){
                    ++valid;
                }
            }
            while(valid == need.size()){
                if(right - left + 1 < len){
                    start = left;
                    len = right - left + 1;
                }
                char d = s[left];
                left++;
                if(need.find(d) != need.end()){
                    if(window[d] == need[d]){
                        valid--;
                    }
                    window[d]--;
                }
            }
            right++;
        }
        return len == INT_MAX?"":s.substr(start,len);
    }
};

567. 字符串的排列

class Solution {
public:
    bool checkInclusion(string s1, string s2) {
        unordered_map<char,int> need,window;
        for(auto c:s1)need[c]++;
        int left = 0,right = 0;
        int valid = 0;
        while(right < s2.size()){
            char tmp = s2[right];
            if(need.find(tmp) != need.end()){
                window[tmp]++;
                if(window[tmp] == need[tmp]){
                    valid++;
                }
            }
            while(right - left + 1 >= s1.size()){
                if(valid == need.size())return true;
                char tmp = s2[left];
                left++;
                if(need.find(tmp) != need.end()){
                    if(window[tmp] == need[tmp]){
                        valid--;
                    }
                    window[tmp]--;
                }
            }
            right++;
        }
        return false;
    }
};

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

class Solution {
public:
    vector<int> findAnagrams(string s, string p) {
        unordered_map<char,int> need,window;
        for(auto c:p)need[c]++;
        vector<int> res;
        int left = 0,right = 0;
        int valid = 0;
        while(right < s.size()){
            char tmp = s[right];
            ++right;
            if(need.count(tmp)){
                window[tmp]++;
                if(window[tmp] == need[tmp])valid++;
            }
            while(right - left >= p.size()){
                if(valid == need.size()){
                    res.push_back(left);
                }
                char c = s[left];
                ++left;
                if(need.count(c)){
                    if(window[c] == need[c]){
                        valid--;
                    }
                    window[c]--;
                }
            }
            
        }
        return res;
    }
};

3. 无重复字符的最长子串

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        unordered_map<char,int> window;
        int left = 0,right = 0;
        int res = 0;
        while(right < s.size()){
            char c = s[right];
            right++;
            window[c]++;
            while(window[c] > 1){
                char d = s[left];
                ++left;
                window[d]--;
            }
            res = max(res,right - left);
        }
        return res;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值