1. 程式人生 > >題目1 : Same Letters In A Row

題目1 : Same Letters In A Row

描述

Litter Ho has a string of lowercase letters. He wants to re-order the letters so that the same letters are placed together in a row.

Unfortunately he can do at most K times of swaps. Each time he can only swap two letters. What is the maximum number of the consective same letters?

Assume the string is "bababbaa" and K = 1. By 1 swapping Little Ho can get "aabbbbaa". "bbbb" has length 4 which is also the maximum number of the consective same letters Little Ho can get.  

輸入

The fist line contains an integer K. (1 <= K <= 100000)  

The second line contain a string of lowercase letters. The length is no more than 100000.

輸出

Output the answer.

樣例輸入

1  
bababbaa

樣例輸出

4

  我腦子裡出現的第一個想法就是 二分,應該也是可以的,只不過複雜度稍微高一點。需要  O(nlog(n)) 的複雜度。

還可以用 滑動視窗來做,利用這樣的一個性質。

感覺這個性質真的是,太妙了。

判斷一個視窗可不可行,只需要 總的 \large ch>=j-i+1 並且不是 ch 的字元小於等於 n 個就行了。

所以我們列舉左端點,確定右端點 就好了。

 

#include<bits/stdc++.h>
using namespace std;

typedef long long LL;
#define rep(i,a,b) for(int i=a;i<b;++i)

const int N=100010;

char str[N];

int sum[N][26];
int num[26];

int n;
int is_ok(int l,int r)
{
    for(int i=0; i<26; i++) {
        int t=sum[r][i]-sum[l-1][i];
        int tmp=r-l+1-t;
        if(num[i]>=r-l+1&&tmp<=n)return 1;
    }
    return 0;
}

int main()
{

    scanf("%d",&n);
    scanf("%s",str+1);

    int len=strlen(str+1);

    for(int i=1; i<=len; i++) {
        num[str[i]-'a']++;
        sum[i][str[i]-'a']=sum[i-1][str[i]-'a']+1;

        for(int j=0; j<26; j++) {
            if(j==str[i]-'a')continue;
            sum[i][j]=sum[i-1][j];
        }
    }

    int l=1,r=1,ans=1;

    while(r<=len) {
        while(r<=len&&is_ok(l,r))r++;
        ans=max(ans,r-l);
        l++;
    }
    printf("%d\n",ans);
    return 0;
}