指尖划过的轨迹,藏着最细腻的答案~
题目:
给你两个整数 w 和 m,以及一个整数数组 arrivals,其中 arrivals[i] 表示第 i 天到达的物品类型(天数从 1 开始编号)。
物品的管理遵循以下规则:
- 每个到达的物品可以被 保留 或 丢弃 ,物品只能在到达当天被丢弃。
- 对于每一天
i,考虑天数范围为[max(1, i - w + 1), i](也就是直到第i天为止最近的w天):- 对于 任何 这样的时间窗口,在被保留的到达物品中,每种类型最多只能出现
m次。 - 如果在第
i天保留该到达物品会导致其类型在该窗口中出现次数 超过m次,那么该物品必须被丢弃。
- 对于 任何 这样的时间窗口,在被保留的到达物品中,每种类型最多只能出现
返回为满足每个 w 天的窗口中每种类型最多出现 m 次,最少 需要丢弃的物品数量。
示例 1:
输入:arrivals = [1,2,1,3,1], w = 4, m = 2
输出:0
解释:
第 1 天,物品 1 到达;窗口中该类型不超过m次,因此保留。
第 2 天,物品 2 到达;第 1 到第 2 天的窗口是可以接受的。
第 3 天,物品 1 到达,窗口[1, 2, 1]中物品 1 出现两次,符合限制。
第 4 天,物品 3 到达,窗口[1, 2, 1, 3]中物品 1 出现两次,仍符合。
第 5 天,物品 1 到达,窗口[2, 1, 3, 1]中物品 1 出现两次,依然有效。
没有任何物品被丢弃,因此返回 0。
示例 2:
输入:arrivals = [1,2,3,3,3,4], w = 3, m = 2
输出:1
解释:
第 1 天,物品 1 到达。我们保留它。
第 2 天,物品 2 到达,窗口[1, 2]是可以的。
第 3 天,物品 3 到达,窗口[1, 2, 3]中物品 3 出现一次。
第 4 天,物品 3 到达,窗口[2, 3, 3]中物品 3 出现两次,允许。
第 5 天,物品 3 到达,窗口[3, 3, 3]中物品 3 出现三次,超过限制,因此该物品必须被丢弃。
第 6 天,物品 4 到达,窗口[3, 4]是可以的。
第 5 天的物品 3 被丢弃,这是最少必须丢弃的数量,因此返回 1。
提示:
分析:
根据题意,我们需要再固定长度的w中判断是否有数字出现超过m次,w即是窗口大小,本题可以使用定长滑动窗口:进入窗口——更新答案——离开窗口。
对于本题来说,由于物品只能当前到达当前丢弃,因此我们可以模拟这个过程:使用哈希表统计窗口中每个数字的数量,如果某个数字出现次数大于m,就需要丢弃,否则将哈希表相应次数加1。
需要注意的是:当某个数字出现次数大于m时,我们已经丢弃,在离开窗口时不能进行二次丢弃,怎样避免这种情况呢?本题所有数字都是正整数,我们可以将已经丢弃的数字设置为一个不可能出现的数(0或负数),在离开窗口减去计数,也不影响我们最终的结果。
AC代码:
class Solution {
public:
int minArrivalsToDiscard(vector<int>& arrivals, int w, int m) {
int n = arrivals.size();
int ans = 0;
unordered_map<int, int> cnt;
for (int i = 0; i < n; i++) {
if (cnt[arrivals[i]] + 1 > m) {
ans++;
arrivals[i] = 0;
} else {
++cnt[arrivals[i]];
}
int left = i - w + 1;
if (left < 0) {
continue;
}
--cnt[arrivals[left]];
}
return ans;
}
};