美团校招-2023.3.18.10点-第二题-k彩色区间-中等

k彩色区间

Problem Description

小美现在有一串彩带,假定每一厘米的彩带上都是一种色彩 因为任务的需要,小美希望从彩带上截取一段,使得彩带中的颜色数量不超过K种。
显然,这样的截取方法可能非常多。于是小美决定尽量长地截取一段你的任务是帮助小美截取尽量长的一段,使得这段彩带上不同的色彩数量不超过K种。

input

第一行两个整数N,K,以空格分开,分别表示彩带有N厘米长,你截取的一段连续的彩带不能超过K种颜色。接下来一行N个整数,每个整数表示一种色彩,相同的整数表示相同的色彩。
1≤N,K≤5000,彩带上的颜色数字介于[1,2000]之间

ouput

一行,一个整数,表示选取的彩带的最大长度。

Sample Input 1

8 3
1 2 3 2 1 4 5 1

Sample Output 1

5

Sample Input 2

8 4
1 2 3 2 1 4 5 1

Sample Output 2

6

题目类型、难度、来源

总体思路:

  • 使用滑动窗口,滑动窗口向右移动。
    • 当前滑动窗口所含的颜色数大于K时,right指针不能移动,因为再增加一个元素,只会令颜色更多,因此要一直向右移动left指针,直到滑动窗口所含颜色数量小于等于K。
    • 当前滑动窗口所含的颜色数小于等于K时,记录最大长度,同时right指针向右移动,以寻找更长的彩带。

AC代码

#include <iostream>
#include <algorithm>
using namespace std;
int main(){
    
    
    int N, K;
    cin >> N >> K;
    int *a = new int[N];
    for (int i = 0; i < N; i++){
    
    
        cin >> a[i];
    }
    int left = 0, right = 0;
    int max_len = -1;
    int color_num = 0;
    int cnt[2050] = {
    
    0};
    while (right != N){
    
    
        if (cnt[a[right]] == 0){
    
    
            // 颜色不存在
            color_num++; 
        }
        cnt[a[right]]++;
        if (color_num > K){
    
    
            while ((color_num > K) && (left <= right)){
    
    
                cnt[a[left]]--;
                if (cnt[a[left]] == 0){
    
    
                    color_num--;
                }
                left++;
            }
        }
        int len = right-left+1;
        if (len > max_len){
    
    
            max_len = len;
        }
        right++;
    }
    cout << max_len;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_40735291/article/details/129667970