Skip to content

Latest commit

 

History

History

2870.Minimum Number of Operations to Make Array Empty

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 
comments difficulty edit_url rating source tags
true
中等
1392
第 114 场双周赛 Q2
贪心
数组
哈希表
计数

English Version

题目描述

给你一个下标从 0 开始的正整数数组 nums 。

你可以对数组执行以下两种操作 任意次 :

  • 从数组中选择 两个 值 相等 的元素,并将它们从数组中 删除 。
  • 从数组中选择 三个 值 相等 的元素,并将它们从数组中 删除 。

请你返回使数组为空的 最少 操作次数,如果无法达成,请返回 -1 。

 

示例 1:

输入:nums = [2,3,3,2,2,4,2,3,4]
输出:4
解释:我们可以执行以下操作使数组为空:
- 对下标为 0 和 3 的元素执行第一种操作,得到 nums = [3,3,2,4,2,3,4] 。
- 对下标为 2 和 4 的元素执行第一种操作,得到 nums = [3,3,4,3,4] 。
- 对下标为 0 ,1 和 3 的元素执行第二种操作,得到 nums = [4,4] 。
- 对下标为 0 和 1 的元素执行第一种操作,得到 nums = [] 。
至少需要 4 步操作使数组为空。

示例 2:

输入:nums = [2,1,2,2,3,3]
输出:-1
解释:无法使数组为空。

 

提示:

  • 2 <= nums.length <= 105
  • 1 <= nums[i] <= 106

解法

方法一:哈希表 + 贪心

我们用一个哈希表 $count$ 统计数组中每个元素出现的次数,然后遍历哈希表,对于每个元素 $x$,如果 $x$ 出现的次数为 $c$,那么我们可以进行 $\lfloor \frac{c+2}{3} \rfloor$ 次操作,将 $x$ 删除,最后我们返回所有元素的操作次数之和即可。

时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是数组的长度。

Python3

class Solution:
    def minOperations(self, nums: List[int]) -> int:
        count = Counter(nums)
        ans = 0
        for c in count.values():
            if c == 1:
                return -1
            ans += (c + 2) // 3
        return ans

Java

class Solution {
    public int minOperations(int[] nums) {
        Map<Integer, Integer> count = new HashMap<>();
        for (int num : nums) {
            // count.put(num, count.getOrDefault(num, 0) + 1);
            count.merge(num, 1, Integer::sum);
        }
        int ans = 0;
        for (int c : count.values()) {
            if (c < 2) {
                return -1;
            }
            int r = c % 3;
            int d = c / 3;
            switch (r) {
                case (0) -> {
                    ans += d;
                }
                default -> {
                    ans += d + 1;
                }
            }
        }
        return ans;
    }
}

C++

class Solution {
public:
    int minOperations(vector<int>& nums) {
        unordered_map<int, int> count;
        for (int num : nums) {
            ++count[num];
        }
        int ans = 0;
        for (auto& [_, c] : count) {
            if (c < 2) {
                return -1;
            }
            ans += (c + 2) / 3;
        }
        return ans;
    }
};

Go

func minOperations(nums []int) (ans int) {
	count := map[int]int{}
	for _, num := range nums {
		count[num]++
	}
	for _, c := range count {
		if c < 2 {
			return -1
		}
		ans += (c + 2) / 3
	}
	return
}

TypeScript

function minOperations(nums: number[]): number {
    const count: Map<number, number> = new Map();
    for (const num of nums) {
        count.set(num, (count.get(num) ?? 0) + 1);
    }
    let ans = 0;
    for (const [_, c] of count) {
        if (c < 2) {
            return -1;
        }
        ans += ((c + 2) / 3) | 0;
    }
    return ans;
}