Minimum Number of Operations to Make Array Empty
MediumUpdated: Aug 2, 2025
Practice on:
Problem
You are given a 0-indexed array nums consisting of positive integers.
There are two types of operations that you can apply on the array any number of times:
- Choose two elements with equal values and delete them from the array.
- Choose three elements with equal values and delete them from the array.
Return _theminimum number of operations required to make the array empty, or _-1 if it is not possible.
Examples
Example 1
Input: nums = [2,3,3,2,2,4,2,3,4]
Output: 4
Explanation: We can apply the following operations to make the array empty:
- Apply the first operation on the elements at indices 0 and 3. The resulting array is nums = [3,3,2,4,2,3,4].
- Apply the first operation on the elements at indices 2 and 4. The resulting array is nums = [3,3,4,3,4].
- Apply the second operation on the elements at indices 0, 1, and 3. The resulting array is nums = [4,4].
- Apply the first operation on the elements at indices 0 and 1. The resulting array is nums = [].
It can be shown that we cannot make the array empty in less than 4 operations.
Example 2
Input: nums = [2,1,2,2,3,3]
Output: -1
Explanation: It is impossible to empty the array.
Constraints
2 <= nums.length <= 10^51 <= nums[i] <= 10^6
Note: This question is the same as [2244: Minimum Rounds to Complete All Tasks.](https://leetcode.com/problems/minimum-rounds-to-complete-all- tasks/description/)
Solution
Method 1 – Greedy Counting (Minimum Rounds)
Intuition
For each value, we can only remove 2 or 3 at a time. If a value appears once, it's impossible. Otherwise, we use as many 3-removals as possible, and the rest as 2-removals.
Approach
- Count the frequency of each value.
- For each frequency:
- If freq == 1, return -1.
- Else, minimum operations = ceil(freq / 3).
- Sum over all values.
Code
C++
#include <vector>
#include <unordered_map>
using namespace std;
class Solution {
public:
int minOperations(vector<int>& nums) {
unordered_map<int, int> freq;
for (int n : nums) freq[n]++;
int ans = 0;
for (auto& [_, f] : freq) {
if (f == 1) return -1;
ans += (f + 2) / 3;
}
return ans;
}
};
Go
func minOperations(nums []int) int {
freq := map[int]int{}
for _, n := range nums { freq[n]++ }
ans := 0
for _, f := range freq {
if f == 1 { return -1 }
ans += (f + 2) / 3
}
return ans
}
Java
import java.util.*;
class Solution {
public int minOperations(int[] nums) {
Map<Integer, Integer> freq = new HashMap<>();
for (int n : nums) freq.put(n, freq.getOrDefault(n, 0) + 1);
int ans = 0;
for (int f : freq.values()) {
if (f == 1) return -1;
ans += (f + 2) / 3;
}
return ans;
}
}
Kotlin
class Solution {
fun minOperations(nums: IntArray): Int {
val freq = mutableMapOf<Int, Int>()
for (n in nums) freq[n] = freq.getOrDefault(n, 0) + 1
var ans = 0
for (f in freq.values) {
if (f == 1) return -1
ans += (f + 2) / 3
}
return ans
}
}
Python
from collections import Counter
class Solution:
def minOperations(self, nums: list[int]) -> int:
freq = Counter(nums)
ans = 0
for f in freq.values():
if f == 1:
return -1
ans += (f + 2) // 3
return ans
Rust
use std::collections::HashMap;
impl Solution {
pub fn min_operations(nums: Vec<i32>) -> i32 {
let mut freq = HashMap::new();
for n in nums { *freq.entry(n).or_insert(0) += 1; }
let mut ans = 0;
for &f in freq.values() {
if f == 1 { return -1; }
ans += (f + 2) / 3;
}
ans
}
}
TypeScript
class Solution {
minOperations(nums: number[]): number {
const freq = new Map<number, number>();
for (const n of nums) freq.set(n, (freq.get(n) ?? 0) + 1);
let ans = 0;
for (const f of freq.values()) {
if (f === 1) return -1;
ans += Math.floor((f + 2) / 3);
}
return ans;
}
}
Complexity
- ⏰ Time complexity:
O(n)— n = length of nums. - 🧺 Space complexity:
O(n)— for frequency map.