版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014303647/article/details/88378465
题目:
解析:其实维护一个m个大小的数组即可,然后每次进入的时候判断一下是否为一种新的颜色,如果是则总的颜色总数color_sum++
,当达到m的时候去的最小坐标和最大坐标,随机更新答案,如果不是新的颜色,就用当前颜色的下标去覆盖即可,有种贪心的思想在里面,时间复杂度O(n*m)
代码:
#include<cstdio>
#include<map>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int MAX = 1000000+10;
const int maxn = 2000+10;
int a[MAX];
int n,m;
int index[maxn];
int main()
{
while(~scanf("%d%d",&n,&m))
{
for(int i = 0;i < n; i++) scanf("%d",&a[i]);
if(n<m)
{
printf("-1\n");
continue;
}
memset(index,0,sizeof(index));
for(int i = 1;i <= m;i++) index[i] = -1;
int min_index,max_index;
int color_num = 0;
int ans = 0x3fffffff;
bool ok = false;
for(int i = 0; i < n; i++)
{
int color = a[i];
if(color==0) continue;
if(index[color]==-1) //没出现过
{
++color_num;
index[color] = i;
if(color_num == m)
{
ok = true;
min_index = index[1];
max_index = index[1];
for(int j=2;j<=m;j++)
{
min_index = min(index[j], min_index);
max_index = max(index[j], max_index);
}
ans = min(max_index - min_index +1,ans) ;
}
}
else
{
index[color] = i;
if(color_num == m)
{
min_index = index[1];
max_index = index[1];
for(int j=2;j<=m;j++)
{
min_index = min(index[j], min_index);
max_index = max(index[j], max_index);
}
ans = min(max_index - min_index +1,ans) ;
}
}
}
if(!ok) printf("-1\n");
else printf("%d\n",ans);
}
return 0;
}
/*
12 5
2 5 3 1 3 2 4 1 0 5 4 3
6
*/
然后看了下牛客给的题解,就是用一个队列来维护颜色队列,时间复杂度也是一样的。
代码:
作者:NotDeep
链接:https://www.nowcoder.com/discuss/160361?type=0&order=0&pos=6&page=1
来源:牛客网
#include <bits/stdc++.h>
using namespace std;
queue<int> q;
int cnt[2005];
int n, m, tot;
int ans = 1e9;
int main() {
cin >> n >> m;
tot = 0;
for(int i = 1; i <= n; i++) {
int x;
cin >> x;
q.push(x);
cnt[x]++;
if(cnt[x] == 1) tot++;
while(cnt[q.front()] > 1 || q.front() == 0) {
cnt[q.front()]--;
if(cnt[q.front()] == 0) tot--;
q.pop();
}
if(tot == m && ans > q.size()) ans = q.size();
}
if(ans != 1000000000) cout << ans;
else cout << -1;
return 0;
}