Medium
题目描述
给你一个整数数组 nums。
在一次操作中,你可以移除当前数组的前三个元素。如果剩余元素少于三个,则移除所有剩余元素。
重复此操作,直到数组为空或不包含重复值。
返回所需的操作次数。
示例 1:
输入:nums = [3,8,3,6,5,8]
输出:1
解释:
在第一次操作中,我们移除前三个元素。剩余元素 [6, 5, 8] 都是不同的,所以我们停止。只需要一次操作。
示例 2:
输入:nums = [2,2]
输出:1
解释:
一次操作后,数组变为空,满足停止条件。
示例 3:
输入:nums = [4,3,5,1,2]
输出:0
解释:
数组中的所有元素都是不同的,因此不需要任何操作。
约束条件:
1 <= nums.length <= 10^51 <= nums[i] <= 10^5
解题思路
解题思路
这道题的核心是模拟题目描述的操作过程。我们需要:
- 检查当前数组是否有重复元素:使用哈希表记录每个元素的出现次数
- 模拟移除操作:如果存在重复元素,移除前三个元素(或剩余所有元素)
- 重复直到满足条件:继续操作直到数组为空或所有元素都不重复
算法步骤:
- 使用指针
start标记当前有效数组的起始位置 - 用哈希表统计当前有效范围内每个元素的出现次数
- 检查是否存在重复元素(出现次数 > 1)
- 如果有重复,执行一次操作:移除前三个元素,更新哈希表和指针
- 重复直到无重复元素或数组为空
时间复杂度优化: 每次操作后只需要更新被移除元素在哈希表中的计数,避免重新遍历整个数组。
这种方法直接模拟了题目要求的过程,逻辑清晰且实现简单。
代码实现
class Solution {
public:
int minOperations(vector<int>& nums) {
int n = nums.size();
int start = 0;
int operations = 0;
while (start < n) {
// 统计当前范围内每个元素的出现次数
unordered_map<int, int> count;
for (int i = start; i < n; i++) {
count[nums[i]]++;
}
// 检查是否有重复元素
bool hasDuplicate = false;
for (auto& p : count) {
if (p.second > 1) {
hasDuplicate = true;
break;
}
}
if (!hasDuplicate) {
break;
}
// 执行一次操作:移除前三个元素
start += 3;
operations++;
}
return operations;
}
};
class Solution:
def minOperations(self, nums: List[int]) -> int:
start = 0
operations = 0
n = len(nums)
while start < n:
# 统计当前范围内每个元素的出现次数
count = {}
for i in range(start, n):
count[nums[i]] = count.get(nums[i], 0) + 1
# 检查是否有重复元素
has_duplicate = any(c > 1 for c in count.values())
if not has_duplicate:
break
# 执行一次操作:移除前三个元素
start += 3
operations += 1
return operations
public class Solution {
public int MinOperations(int[] nums) {
int start = 0;
int operations = 0;
int n = nums.Length;
while (start < n) {
// 统计当前范围内每个元素的出现次数
Dictionary<int, int> count = new Dictionary<int, int>();
for (int i = start; i < n; i++) {
if (count.ContainsKey(nums[i])) {
count[nums[i]]++;
} else {
count[nums[i]] = 1;
}
}
// 检查是否有重复元素
bool hasDuplicate = false;
foreach (var kvp in count) {
if (kvp.Value > 1) {
hasDuplicate = true;
break;
}
}
if (!hasDuplicate) {
break;
}
// 执行一次操作:移除前三个元素
start += 3;
operations++;
}
return operations;
}
}
var minOperations = function(nums) {
let start = 0;
let operations = 0;
const n = nums.length;
while (start < n) {
// 统计当前范围内每个元素的出现次数
const count = new Map();
for (let i = start; i < n; i++) {
count.set(nums[i], (count.get(nums[i]) || 0) + 1);
}
// 检查是否有重复元素
let hasDuplicate = false;
for (const [num, cnt] of count) {
if (cnt > 1) {
hasDuplicate = true;
break;
}
}
if (!hasDuplicate) {
break;
}
// 执行一次操作:移除前三个元素
start += 3;
operations++;
}
return operations;
};
复杂度分析
| 复杂度类型 | 复杂度 | 说明 |
|---|---|---|
| 时间复杂度 | O(n²) | 最坏情况下需要 O(n/3) 次操作,每次操作需要 O(n) 时间统计元素频次 |
| 空间复杂度 | O(n) | 哈希表存储元素频次,最多存储 n 个不同元素 |