diff --git a/solution/3600-3699/3679.Minimum Discards to Balance Inventory/README.md b/solution/3600-3699/3679.Minimum Discards to Balance Inventory/README.md index 99132adf2e459..fd7515a9fef81 100644 --- a/solution/3600-3699/3679.Minimum Discards to Balance Inventory/README.md +++ b/solution/3600-3699/3679.Minimum Discards to Balance Inventory/README.md @@ -91,32 +91,141 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3600-3699/3679.Mi -### 方法一 +### 方法一:模拟 + 滑动窗口 + +我们用一个哈希表 $\textit{cnt}$ 来记录当前窗口中每种物品的数量,用一个数组 $\textit{marked}$ 来记录每个物品是否被保留。 + +我们从左到右遍历数组,对于每个物品 $x$: + +1. 如果当前天数 $i$ 大于等于窗口大小 $w$,则需要将窗口最左侧的物品数量减去 $\textit{marked}[i - w]$(如果该物品被保留的话)。 +2. 如果当前物品在窗口中的数量超过了 $m$,则需要丢弃该物品。 +3. 否则,保留该物品,并将其数量加一。 + +最终,答案即为被丢弃的物品数量。 + +时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组长度。 #### Python3 ```python - +class Solution: + def minArrivalsToDiscard(self, arrivals: List[int], w: int, m: int) -> int: + cnt = Counter() + n = len(arrivals) + marked = [0] * n + ans = 0 + for i, x in enumerate(arrivals): + if i >= w: + cnt[arrivals[i - w]] -= marked[i - w] + if cnt[x] >= m: + ans += 1 + else: + marked[i] = 1 + cnt[x] += 1 + return ans ``` #### Java ```java - +class Solution { + public int minArrivalsToDiscard(int[] arrivals, int w, int m) { + Map cnt = new HashMap<>(); + int n = arrivals.length; + int[] marked = new int[n]; + int ans = 0; + for (int i = 0; i < n; i++) { + int x = arrivals[i]; + if (i >= w) { + int prev = arrivals[i - w]; + cnt.merge(prev, -marked[i - w], Integer::sum); + } + if (cnt.getOrDefault(x, 0) >= m) { + ans++; + } else { + marked[i] = 1; + cnt.merge(x, 1, Integer::sum); + } + } + return ans; + } +} ``` #### C++ ```cpp - +class Solution { +public: + int minArrivalsToDiscard(vector& arrivals, int w, int m) { + unordered_map cnt; + int n = arrivals.size(); + vector marked(n, 0); + int ans = 0; + for (int i = 0; i < n; i++) { + int x = arrivals[i]; + if (i >= w) { + cnt[arrivals[i - w]] -= marked[i - w]; + } + if (cnt[x] >= m) { + ans++; + } else { + marked[i] = 1; + cnt[x] += 1; + } + } + return ans; + } +}; ``` #### Go ```go +func minArrivalsToDiscard(arrivals []int, w int, m int) (ans int) { + cnt := make(map[int]int) + n := len(arrivals) + marked := make([]int, n) + for i, x := range arrivals { + if i >= w { + cnt[arrivals[i-w]] -= marked[i-w] + } + if cnt[x] >= m { + ans++ + } else { + marked[i] = 1 + cnt[x]++ + } + } + return +} +``` +#### TypeScript + +```ts +function minArrivalsToDiscard(arrivals: number[], w: number, m: number): number { + const cnt = new Map(); + const n = arrivals.length; + const marked = Array(n).fill(0); + let ans = 0; + + for (let i = 0; i < n; i++) { + const x = arrivals[i]; + if (i >= w) { + cnt.set(arrivals[i - w], (cnt.get(arrivals[i - w]) || 0) - marked[i - w]); + } + if ((cnt.get(x) || 0) >= m) { + ans++; + } else { + marked[i] = 1; + cnt.set(x, (cnt.get(x) || 0) + 1); + } + } + return ans; +} ``` diff --git a/solution/3600-3699/3679.Minimum Discards to Balance Inventory/README_EN.md b/solution/3600-3699/3679.Minimum Discards to Balance Inventory/README_EN.md index ea29ebef3bf92..2d414a28265c2 100644 --- a/solution/3600-3699/3679.Minimum Discards to Balance Inventory/README_EN.md +++ b/solution/3600-3699/3679.Minimum Discards to Balance Inventory/README_EN.md @@ -89,32 +89,141 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3600-3699/3679.Mi -### Solution 1 +### Solution 1: Simulation + Sliding Window + +We use a hash map $\textit{cnt}$ to record the quantity of each item type in the current window, and an array $\textit{marked}$ to record whether each item is kept. + +We iterate through the array from left to right. For each item $x$: + +1. If the current day $i$ is greater than or equal to the window size $w$, we subtract $\textit{marked}[i - w]$ from the count of the leftmost item in the window (if that item was kept). +2. If the quantity of the current item in the window exceeds $m$, we discard the item. +3. Otherwise, we keep the item and increment its count. + +Finally, the answer is the number of items discarded. + +The time complexity is $O(n)$, and the space complexity is $O(n)$, where $n$ is the length of the array. #### Python3 ```python - +class Solution: + def minArrivalsToDiscard(self, arrivals: List[int], w: int, m: int) -> int: + cnt = Counter() + n = len(arrivals) + marked = [0] * n + ans = 0 + for i, x in enumerate(arrivals): + if i >= w: + cnt[arrivals[i - w]] -= marked[i - w] + if cnt[x] >= m: + ans += 1 + else: + marked[i] = 1 + cnt[x] += 1 + return ans ``` #### Java ```java - +class Solution { + public int minArrivalsToDiscard(int[] arrivals, int w, int m) { + Map cnt = new HashMap<>(); + int n = arrivals.length; + int[] marked = new int[n]; + int ans = 0; + for (int i = 0; i < n; i++) { + int x = arrivals[i]; + if (i >= w) { + int prev = arrivals[i - w]; + cnt.merge(prev, -marked[i - w], Integer::sum); + } + if (cnt.getOrDefault(x, 0) >= m) { + ans++; + } else { + marked[i] = 1; + cnt.merge(x, 1, Integer::sum); + } + } + return ans; + } +} ``` #### C++ ```cpp - +class Solution { +public: + int minArrivalsToDiscard(vector& arrivals, int w, int m) { + unordered_map cnt; + int n = arrivals.size(); + vector marked(n, 0); + int ans = 0; + for (int i = 0; i < n; i++) { + int x = arrivals[i]; + if (i >= w) { + cnt[arrivals[i - w]] -= marked[i - w]; + } + if (cnt[x] >= m) { + ans++; + } else { + marked[i] = 1; + cnt[x] += 1; + } + } + return ans; + } +}; ``` #### Go ```go +func minArrivalsToDiscard(arrivals []int, w int, m int) (ans int) { + cnt := make(map[int]int) + n := len(arrivals) + marked := make([]int, n) + for i, x := range arrivals { + if i >= w { + cnt[arrivals[i-w]] -= marked[i-w] + } + if cnt[x] >= m { + ans++ + } else { + marked[i] = 1 + cnt[x]++ + } + } + return +} +``` +#### TypeScript + +```ts +function minArrivalsToDiscard(arrivals: number[], w: number, m: number): number { + const cnt = new Map(); + const n = arrivals.length; + const marked = Array(n).fill(0); + let ans = 0; + + for (let i = 0; i < n; i++) { + const x = arrivals[i]; + if (i >= w) { + cnt.set(arrivals[i - w], (cnt.get(arrivals[i - w]) || 0) - marked[i - w]); + } + if ((cnt.get(x) || 0) >= m) { + ans++; + } else { + marked[i] = 1; + cnt.set(x, (cnt.get(x) || 0) + 1); + } + } + return ans; +} ``` diff --git a/solution/3600-3699/3679.Minimum Discards to Balance Inventory/Solution.cpp b/solution/3600-3699/3679.Minimum Discards to Balance Inventory/Solution.cpp new file mode 100644 index 0000000000000..a501d98db5715 --- /dev/null +++ b/solution/3600-3699/3679.Minimum Discards to Balance Inventory/Solution.cpp @@ -0,0 +1,22 @@ +class Solution { +public: + int minArrivalsToDiscard(vector& arrivals, int w, int m) { + unordered_map cnt; + int n = arrivals.size(); + vector marked(n, 0); + int ans = 0; + for (int i = 0; i < n; i++) { + int x = arrivals[i]; + if (i >= w) { + cnt[arrivals[i - w]] -= marked[i - w]; + } + if (cnt[x] >= m) { + ans++; + } else { + marked[i] = 1; + cnt[x] += 1; + } + } + return ans; + } +}; diff --git a/solution/3600-3699/3679.Minimum Discards to Balance Inventory/Solution.go b/solution/3600-3699/3679.Minimum Discards to Balance Inventory/Solution.go new file mode 100644 index 0000000000000..ae49c0b7f7390 --- /dev/null +++ b/solution/3600-3699/3679.Minimum Discards to Balance Inventory/Solution.go @@ -0,0 +1,17 @@ +func minArrivalsToDiscard(arrivals []int, w int, m int) (ans int) { + cnt := make(map[int]int) + n := len(arrivals) + marked := make([]int, n) + for i, x := range arrivals { + if i >= w { + cnt[arrivals[i-w]] -= marked[i-w] + } + if cnt[x] >= m { + ans++ + } else { + marked[i] = 1 + cnt[x]++ + } + } + return +} diff --git a/solution/3600-3699/3679.Minimum Discards to Balance Inventory/Solution.java b/solution/3600-3699/3679.Minimum Discards to Balance Inventory/Solution.java new file mode 100644 index 0000000000000..5262b4dbe3a1c --- /dev/null +++ b/solution/3600-3699/3679.Minimum Discards to Balance Inventory/Solution.java @@ -0,0 +1,22 @@ +class Solution { + public int minArrivalsToDiscard(int[] arrivals, int w, int m) { + Map cnt = new HashMap<>(); + int n = arrivals.length; + int[] marked = new int[n]; + int ans = 0; + for (int i = 0; i < n; i++) { + int x = arrivals[i]; + if (i >= w) { + int prev = arrivals[i - w]; + cnt.merge(prev, -marked[i - w], Integer::sum); + } + if (cnt.getOrDefault(x, 0) >= m) { + ans++; + } else { + marked[i] = 1; + cnt.merge(x, 1, Integer::sum); + } + } + return ans; + } +} diff --git a/solution/3600-3699/3679.Minimum Discards to Balance Inventory/Solution.py b/solution/3600-3699/3679.Minimum Discards to Balance Inventory/Solution.py new file mode 100644 index 0000000000000..be2a58fe3e20c --- /dev/null +++ b/solution/3600-3699/3679.Minimum Discards to Balance Inventory/Solution.py @@ -0,0 +1,15 @@ +class Solution: + def minArrivalsToDiscard(self, arrivals: List[int], w: int, m: int) -> int: + cnt = Counter() + n = len(arrivals) + marked = [0] * n + ans = 0 + for i, x in enumerate(arrivals): + if i >= w: + cnt[arrivals[i - w]] -= marked[i - w] + if cnt[x] >= m: + ans += 1 + else: + marked[i] = 1 + cnt[x] += 1 + return ans diff --git a/solution/3600-3699/3679.Minimum Discards to Balance Inventory/Solution.ts b/solution/3600-3699/3679.Minimum Discards to Balance Inventory/Solution.ts new file mode 100644 index 0000000000000..f63cb0d312df8 --- /dev/null +++ b/solution/3600-3699/3679.Minimum Discards to Balance Inventory/Solution.ts @@ -0,0 +1,20 @@ +function minArrivalsToDiscard(arrivals: number[], w: number, m: number): number { + const cnt = new Map(); + const n = arrivals.length; + const marked = Array(n).fill(0); + let ans = 0; + + for (let i = 0; i < n; i++) { + const x = arrivals[i]; + if (i >= w) { + cnt.set(arrivals[i - w], (cnt.get(arrivals[i - w]) || 0) - marked[i - w]); + } + if ((cnt.get(x) || 0) >= m) { + ans++; + } else { + marked[i] = 1; + cnt.set(x, (cnt.get(x) || 0) + 1); + } + } + return ans; +}