LeetCode 3396: Minimum Number of Operations to Make Elements in Array Distinct (Suffix Distinct + Math)
LeetCode 3396ArrayHash SetToday we solve LeetCode 3396 - Minimum Number of Operations to Make Elements in Array Distinct.
Source: https://leetcode.com/problems/minimum-number-of-operations-to-make-elements-in-array-distinct/
English
Problem Summary
Each operation removes the first 3 elements. Return the minimum operations needed so remaining array elements are all distinct.
Key Insight
Find the earliest index that must be removed. Scan from right to left and keep a set of seen values. Once a duplicate appears at index i, all prefixes up to i must be removed.
Optimal Algorithm Steps
1) Scan from right, insert into set.
2) First duplicate at index i gives required removed count i+1.
3) Answer is ceil((i+1)/3).
4) If no duplicate is found, answer is 0.
Complexity Analysis
Time: O(n). Space: O(n).
Reference Implementations (Java / Go / C++ / Python / JavaScript)
class Solution {
public int minimumOperations(int[] nums) {
Set<Integer> seen = new HashSet<>();
for (int i = nums.length - 1; i >= 0; i--) {
if (!seen.add(nums[i])) {
return (i + 3) / 3;
}
}
return 0;
}
}func minimumOperations(nums []int) int {
seen := map[int]bool{}
for i := len(nums)-1; i >= 0; i-- {
if seen[nums[i]] {
return (i + 3) / 3
}
seen[nums[i]] = true
}
return 0
}class Solution {
public:
int minimumOperations(vector<int>& nums) {
unordered_set<int> seen;
for (int i = (int)nums.size() - 1; i >= 0; --i) {
if (seen.count(nums[i])) return (i + 3) / 3;
seen.insert(nums[i]);
}
return 0;
}
};class Solution:
def minimumOperations(self, nums: list[int]) -> int:
seen = set()
for i in range(len(nums) - 1, -1, -1):
if nums[i] in seen:
return (i + 3) // 3
seen.add(nums[i])
return 0/**
* @param {number[]} nums
* @return {number}
*/
var minimumOperations = function(nums) {
const seen = new Set();
for (let i = nums.length - 1; i >= 0; i--) {
if (seen.has(nums[i])) return Math.floor((i + 3) / 3);
seen.add(nums[i]);
}
return 0;
};中文
题目概述
每次操作删除数组最前面的 3 个元素,求最少操作次数,使剩余元素两两不同。
核心思路
从右向左扫描,维护后缀去重集合。第一次遇到重复位置 i 时,说明前 i+1 个元素必须被删掉。
最优算法步骤
1)从右向左将元素加入哈希集合。
2)若当前值已在集合中,返回 ceil((i+1)/3)。
3)全部无重复则返回 0。
复杂度分析
时间复杂度 O(n),空间复杂度 O(n)。
多语言参考实现(Java / Go / C++ / Python / JavaScript)
class Solution {
public int minimumOperations(int[] nums) {
Set<Integer> seen = new HashSet<>();
for (int i = nums.length - 1; i >= 0; i--) {
if (!seen.add(nums[i])) {
return (i + 3) / 3;
}
}
return 0;
}
}func minimumOperations(nums []int) int {
seen := map[int]bool{}
for i := len(nums)-1; i >= 0; i-- {
if seen[nums[i]] {
return (i + 3) / 3
}
seen[nums[i]] = true
}
return 0
}class Solution {
public:
int minimumOperations(vector<int>& nums) {
unordered_set<int> seen;
for (int i = (int)nums.size() - 1; i >= 0; --i) {
if (seen.count(nums[i])) return (i + 3) / 3;
seen.insert(nums[i]);
}
return 0;
}
};class Solution:
def minimumOperations(self, nums: list[int]) -> int:
seen = set()
for i in range(len(nums) - 1, -1, -1):
if nums[i] in seen:
return (i + 3) // 3
seen.add(nums[i])
return 0/**
* @param {number[]} nums
* @return {number}
*/
var minimumOperations = function(nums) {
const seen = new Set();
for (let i = nums.length - 1; i >= 0; i--) {
if (seen.has(nums[i])) return Math.floor((i + 3) / 3);
seen.add(nums[i]);
}
return 0;
};
Comments