Easy
题目描述
给你一个整数数组 nums。你需要确保数组中的元素互不相同。为了实现这个目标,你可以执行以下操作任意次数:
- 从数组开头移除 3 个元素。如果数组少于 3 个元素,则移除所有剩余元素。
注意,空数组被认为具有互不相同的元素。返回使数组元素互不相同所需的最少操作次数。
示例 1:
输入:nums = [1,2,3,4,2,3,3,5,7]
输出:2
解释:
- 第一次操作,移除前 3 个元素,数组变为 [4, 2, 3, 3, 5, 7]。
- 第二次操作,移除接下来的 3 个元素,数组变为 [3, 5, 7],元素互不相同。
因此,答案是 2。
示例 2:
输入:nums = [4,5,6,4,4]
输出:2
解释:
- 第一次操作,移除前 3 个元素,数组变为 [4, 4]。
- 第二次操作,移除所有剩余元素,数组变为空。
因此,答案是 2。
示例 3:
输入:nums = [6,7,8,9]
输出:0
解释:
数组已经包含互不相同的元素。因此,答案是 0。
约束条件:
1 <= nums.length <= 1001 <= nums[i] <= 100
提示:
- 约束条件较小,可以尝试暴力解法。
解题思路
解题思路
由于数组长度最多100,我们可以使用暴力模拟的方法来解决这个问题。
核心思路:
- 每次操作都是从数组开头移除3个元素(如果不足3个则移除所有)
- 我们需要检查当前数组是否所有元素都互不相同
- 如果不满足条件,继续执行操作,直到满足为止
具体步骤:
- 使用哈希表(或集合)来检查数组中是否有重复元素
- 如果没有重复元素,直接返回0
- 如果有重复元素,模拟移除前3个元素的操作
- 重复步骤1-3,直到数组为空或所有元素互不相同
- 返回操作次数
时间复杂度优化: 由于每次操作最多移除3个元素,最多需要⌈n/3⌉次操作,每次检查重复需要O(n)时间,总体复杂度是可接受的。
这种方法简单直观,符合题目暴力求解的提示,在给定的约束条件下效率足够。
代码实现
class Solution {
public:
int minimumOperations(vector<int>& nums) {
int operations = 0;
while (!nums.empty()) {
// 检查当前数组是否所有元素都互不相同
unordered_set<int> seen;
bool hasDuplicate = false;
for (int num : nums) {
if (seen.count(num)) {
hasDuplicate = true;
break;
}
seen.insert(num);
}
// 如果没有重复元素,返回操作次数
if (!hasDuplicate) {
break;
}
// 移除前3个元素(如果不足3个则移除所有)
int removeCount = min(3, (int)nums.size());
nums.erase(nums.begin(), nums.begin() + removeCount);
operations++;
}
return operations;
}
};
class Solution:
def minimumOperations(self, nums: List[int]) -> int:
operations = 0
while nums:
# 检查当前数组是否所有元素都互不相同
if len(set(nums)) == len(nums):
break
# 移除前3个元素(如果不足3个则移除所有)
remove_count = min(3, len(nums))
nums = nums[remove_count:]
operations += 1
return operations
public class Solution {
public int MinimumOperations(int[] nums) {
var numsList = new List<int>(nums);
int operations = 0;
while (numsList.Count > 0) {
// 检查当前数组是否所有元素都互不相同
var seen = new HashSet<int>();
bool hasDuplicate = false;
foreach (int num in numsList) {
if (seen.Contains(num)) {
hasDuplicate = true;
break;
}
seen.Add(num);
}
// 如果没有重复元素,返回操作次数
if (!hasDuplicate) {
break;
}
// 移除前3个元素(如果不足3个则移除所有)
int removeCount = Math.Min(3, numsList.Count);
numsList.RemoveRange(0, removeCount);
operations++;
}
return operations;
}
}
var minimumOperations = function(nums) {
let operations = 0;
while (nums.length > 0) {
// 检查当前数组是否所有元素都互不相同
const seen = new Set();
let hasDuplicate = false;
for (const num of nums) {
if (seen.has(num)) {
hasDuplicate = true;
break;
}
seen.add(num);
}
// 如果没有重复元素,返回操作次数
if (!hasDuplicate) {
break;
}
// 移除前3个元素(如果不足3个则移除所有)
const removeCount = Math.min(3, nums.length);
nums.splice(0, removeCount);
operations++;
}
return operations;
};
复杂度分析
| 复杂度类型 | 时间复杂度 | 空间复杂度 |
|---|---|---|
| 最坏情况 | O(n²) | O(n) |
| 平均情况 | O(n²) | O(n) |
说明:
- 时间复杂度:最多进行⌈n/3⌉次操作,每次操作需要O(n)时间检查重复元素,总体为O(n²)
- 空间复杂度:使用哈希表存储元素,最多需要O(n)的额外空间