牛牛的魔法卡(解题报告)
将每个魔法卡的坐标与种类放入一个结构体(方便理解)中,按坐标从小到大排序,然后用两个指针l, r指向开头,每次挪动尾指针r,用一个数组cnt记录每种魔法卡的出现次数,若头一次出现,则种类总数sum++,当魔法卡种类总数sum==k时,再一次次挪动头指针l,直到种类为a[l].id的魔法卡个数cnt[a[l].id]==1时,跳出while循环,然后更新答案,此时在更新左指针l和相应的种类个数,直到r==n时退出最外层循环,输出答案.
时间复杂度:O(nlog(n)) 因为有一个排序的过程。
额外空间复杂度:O(max(n,k))
标程代码:
const int MAXN = 1e6+5;
struct Node {
int id, val;
}a[MAXN];
bool cmp(Node A, Node B) {
return A.val < B.val;
}
int cnt[55];
class Solution {
public:
/**
*
* @param n int整型
* @param k int整型
* @param card int整型vector<vector<>>
* @return int整型
*/
int solve(int n, int k, vector<vector<int> >& card) {
// write code here
for(int i=0; i<n; i++) {
a[i].id = card[i][0];
a[i].val = card[i][1];
}
sort(a, a+n, cmp);
int ans = INT_MAX, l = 0, r = 0, sum = 0;
memset(cnt, 0, sizeof cnt);
while(r < n) {
if(cnt[a[r].id] == 0) sum++;
cnt[a[r++].id]++;
if(sum == k) {
while(cnt[a[l].id] > 1) cnt[a[l++].id]--;
int tmp = a[r-1].val-a[l].val;
if(ans > tmp) ans = tmp;
cnt[a[l++].id]--;
sum--;
}
}
if(ans == INT_MAX) ans = -1;
return ans;
}
};