牛牛的魔法卡(解题报告)
将每个魔法卡的坐标与种类放入一个结构体(方便理解)中,按坐标从小到大排序,然后用两个指针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; } };