424. 替换后的最长重复字符 滑动窗口,好题

解题思路

  1. 原本的解题思路,枚举最长字符串的第一个字符,然后不断向后寻找最长的字符串,思路错误,因为s里面的字符不一定是最长字符串的第一个字符。

  2. 正确的思路:滑动窗口

    设置一个left指针,一个right指针:

    left=right=0;

    设置一个res=0,记录我们的结果。

    设置maxCharNum维护窗口中也就是[left,right)区间内的出现最多的字符的个数,这样剩下的字符个数就是remain=right-left-maxCharNum,当remain<k的时候,所有的字符可以被替换,得到一个窗口的最大值,在这个窗口满足这个条件的过程中,不断的取res=max(res,right-left)的最大值,这就是我们最终的答案。

    maxCharNum的维护只需要在right向右移动的时候维护。

    什么时候right++?

    1. remain=right-left-maxCharNum,当remain<=k的时候,right++

    什么时候left++?

    当满足remain=right-left-maxCharNum,当remain>k的时候,remain++。

    leetcode题解

    int left=0,right=0;
    int res=0;
    int chars[26]={0};
    int maxCharNum=0;
    while(right<n){
        int index=(int)(s[right]-'A');
        chars[index]++;
        maxCharNum=max(maxCharNum,chars[index]);
        right++;
        if(maxCharNum+k<right-left){
            index=(int)(s[left]-'A');
            chars[index]--;
            left++;
        }
        res=max(res,right-left);
    }
    return res;
    

代码

class Solution {
public:
    int n,k;
    int characterReplacement(string s, int k) {
        n=s.size();
        this->k=k;
        if(n<=1){
            return n;
        }
        // int left=0,right=1;
        // int res=0,remain=k;
        // char curChar=s[0];
        // while(right<n){
        //     remain=k;
        //     curChar=s[left];
        //     right=left+1;
        //     // cout<<"remain: "<<remain<<" "<<curChar<<endl;
        //     while(remain>0&&right<n){
        //         if(s[right]!=curChar){
        //             remain--;
        //         }
        //         right++;
        //         // cout<<"here1: "<<right<<" "<<remain<<" "<<s[right]<<endl;
        //     }
        //     while(right<n&&s[right]==curChar){
        //         right++;
        //         // cout<<"here2: "<<s[right]<<endl;
        //     }
        //     // cout<<left<<" "<<right<<" "<<right-left<<endl;
        //     res=max(res,right-left);
        //     while(left<right&&s[left]==curChar){
        //         left++;
        //     }
        // }
        // reverse(s.begin(),s.end());
        // left=0,right=1;
        // remain=k;
        // curChar=s[0];
        // while(right<n){
        //     remain=k;
        //     curChar=s[left];
        //     right=left+1;
        //     // cout<<"remain: "<<remain<<" "<<curChar<<endl;
        //     while(remain>0&&right<n){
        //         if(s[right]!=curChar){
        //             remain--;
        //         }
        //         right++;
        //         // cout<<"here1: "<<right<<" "<<remain<<" "<<s[right]<<endl;
        //     }
        //     while(right<n&&s[right]==curChar){
        //         right++;
        //         // cout<<"here2: "<<s[right]<<endl;
        //     }
        //     // cout<<left<<" "<<right<<" "<<right-left<<endl;
        //     res=max(res,right-left);
        //     while(left<right&&s[left]==curChar){
        //         left++;
        //     }
        // }
        
        int left=0,right=0;
        int res=0;
        int chars[26]={0};
        int maxCharNum=0;
        while(right<n){
            int index=(int)(s[right]-'A');
            chars[index]++;
            maxCharNum=max(maxCharNum,chars[index]);
            right++;
            if(maxCharNum+k<right-left){
                index=(int)(s[left]-'A');
                chars[index]--;
                left++;
            }
            res=max(res,right-left);
        }
        return res;
    }
};
​```
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值