校招真题题解:子串长度

2023/06/24 leetcode 算法 共 940 字,约 3 分钟

这道题是字节21年算法方向的编程题。原题如下:

子串长度

时间限制: 1000MS 内存限制: 65536KB

题目描述:

有一个仅包含’a’和’b’两种字符的字符串s,长度为n,每次操作可以把一个字符做一次转换(把一个’a’设置为’b’,或者把一个’b’置成’a’);但是操作的次数有上限m,问在有限的操作数范围内,能够得到最大连续的相同字符的子串的长度是多少。

输入描述

第一行两个整数 n , m (1<=m<=n<=50000),第二行为长度为n且只包含’a’和’b’的字符串s。

输出描述

输出在操作次数不超过 m 的情况下,能够得到的 最大连续 全’a’子串或全’b’子串的长度。

样例输入

8 1
aabaabaa

样例输出

5

其实这道题并不难,但是我没看出来做题的思路,在那里用回溯做,复杂度又高,一顿操作就过了66%。这道题用双指针就可以了,和之前的双指针题目是一个类型,只用维护好a_cntb_cnt就可以,当a_cnt或者b_cnt小于m时直接进行翻转可以保证当前字符串全部翻转成一样。只有当两者都超过m时才需要移动left

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;

int main(){
  int n,m;
  cin>>n>>m;
  string s;
  cin>>s;
  int left=0, right=0;
  int a_cnt=0, b_cnt=0;
  int res=0;
  while(right<n){
    if(s[right]=='a'){
      a_cnt++;
    }
    else{
      b_cnt++;
    }
    if(a_cnt>m&&b_cnt>m){
      if(s[right]=='a'){
        while(s[left]=='b'){
          ++left;
          b_cnt--;
        }
        ++left;
        a_cnt--;
      }
      else{
        while(s[left]=='a'){
          ++left;
          a_cnt--;
        }
        ++left;
        b_cnt--;
      }
    }
    res=max(res,right-left+1);
    ++right;
  }
  cout<<res<<endl;
}

文档信息

Search

    Table of Contents