LeetCode 2869: Minimum Operations to Collect Elements (Greedy / Hash Set)
English
We need the smallest suffix that already contains every value in [1..k]. Scan from right to left, add numbers <= k into a set, and stop once set size is k. If we stop at index i, operations = n - i.
class Solution {
public int minOperations(List<Integer> nums, int k) {
Set<Integer> seen = new HashSet<>();
for (int i = nums.size() - 1; i >= 0; i--) {
int x = nums.get(i);
if (x <= k) seen.add(x);
if (seen.size() == k) return nums.size() - i;
}
return nums.size();
}
}func minOperations(nums []int, k int) int {
seen := map[int]bool{}
n := len(nums)
for i := n - 1; i >= 0; i-- {
x := nums[i]
if x <= k {
seen[x] = true
}
if len(seen) == k {
return n - i
}
}
return n
}class Solution {
public:
int minOperations(vector<int>& nums, int k) {
unordered_set<int> seen;
int n = nums.size();
for (int i = n - 1; i >= 0; --i) {
if (nums[i] <= k) seen.insert(nums[i]);
if ((int)seen.size() == k) return n - i;
}
return n;
}
};class Solution:
def minOperations(self, nums: List[int], k: int) -> int:
seen = set()
n = len(nums)
for i in range(n - 1, -1, -1):
if nums[i] <= k:
seen.add(nums[i])
if len(seen) == k:
return n - i
return nvar minOperations = function(nums, k) {
const seen = new Set();
const n = nums.length;
for (let i = n - 1; i >= 0; i--) {
if (nums[i] <= k) seen.add(nums[i]);
if (seen.size === k) return n - i;
}
return n;
};中文
目标是找到最短后缀,使它已经覆盖 [1..k] 的所有数字。我们从右往左扫描,把 <= k 的数字放入集合;当集合大小达到 k 时,当前后缀长度就是最少操作数,即 n - i。
class Solution {
public int minOperations(List<Integer> nums, int k) {
Set<Integer> seen = new HashSet<>();
for (int i = nums.size() - 1; i >= 0; i--) {
int x = nums.get(i);
if (x <= k) seen.add(x);
if (seen.size() == k) return nums.size() - i;
}
return nums.size();
}
}func minOperations(nums []int, k int) int {
seen := map[int]bool{}
n := len(nums)
for i := n - 1; i >= 0; i-- {
x := nums[i]
if x <= k {
seen[x] = true
}
if len(seen) == k {
return n - i
}
}
return n
}class Solution {
public:
int minOperations(vector<int>& nums, int k) {
unordered_set<int> seen;
int n = nums.size();
for (int i = n - 1; i >= 0; --i) {
if (nums[i] <= k) seen.insert(nums[i]);
if ((int)seen.size() == k) return n - i;
}
return n;
}
};class Solution:
def minOperations(self, nums: List[int], k: int) -> int:
seen = set()
n = len(nums)
for i in range(n - 1, -1, -1):
if nums[i] <= k:
seen.add(nums[i])
if len(seen) == k:
return n - i
return nvar minOperations = function(nums, k) {
const seen = new Set();
const n = nums.length;
for (let i = n - 1; i >= 0; i--) {
if (nums[i] <= k) seen.add(nums[i]);
if (seen.size === k) return n - i;
}
return n;
};