[LeetCode] 滑动窗口

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

设置两个指针l,r。l和r分别指向子串的首尾元素。l从0开始且基于l进行for循环,r从-1开始且在for循环中利用while对r进行遍历。

注意:l移动后说明l-1已经退出窗口了,因此要在set中清除l-1;while循环中遍历的实际上是r+1,这样当r+1为重复元素时,保存的r即为符合要求的窗口右边界

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        unordered_set<char> hash;
        int r = -1; //右指针,初始在字符串边界之外
        int ans = 0;

        for(int l = 0; l < s.size(); l++) { //l为左指针
            //左指针左移后要更新hash
            if(l != 0)
                hash.erase(s[l-1]);
            //右指针移动
            while(r + 1 < s.size() && !hash.count(s[r+1])) {
                hash.insert(s[r+1]);
                ++r;
            }
            //子串从l到r
            ans = max(ans, r - l + 1);
        }
        return ans;
    }
};

424. 替换后的最长重复字符 - 力扣(LeetCode) (leetcode-cn.com)

本题要求一个最长重复字符串,该串可通过对某一子串修改最多k次得到。误区是真的用k次来替换字符。实际上可以得到判断当前子串是否符合要求的条件:当前子串长度(即子串中所有字符的出现次数和) - 子串中出现次数最多的字符的出现次数 <= k。也就是说当~ - ~ > k时,就该调整子串范围了。

滑动窗口的原理:l和r指针,r负责向右扩展,遍历新字符;当不符合要求时,l右移。

注意:和上一题一样,l右移前一定要更新状态,本题是l对应的字符出现次数-1然后l再右移。

class Solution {
public:
    int characterReplacement(string s, int k) {
        vector<int> nums(26, 0);
        int l = 0, r;
        int maxNum = 0; //用于记录当前出现次数最多的字符的出现次数
        for(r = 0; r < s.size(); r++) { //右指针用于扩展,遍历新的字符
            ++nums[s[r] - 'A']; //遍历到的字符,记录更新
            maxNum = max(maxNum, nums[s[r]-'A']); //比较刚刚遍历到的字符是否出现次数是最多的
            //如果当前子串不能通过k次修改来达到全体字符相同,则左指针移动
            if((r - l + 1) - maxNum > k) {
                --nums[s[l]-'A'];
                ++l;
            }
        }
        return r - l;
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值