跳转至

3779. 得到互不相同元素的最少操作次数

题目描述

给你一个整数数组 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 <= 105
  • 1 <= nums[i] <= 105

解法

方法一:哈希表 + 倒序遍历

我们可以倒序遍历数组 \(\textit{nums}\),并使用哈希表 \(\textit{st}\) 记录已经遍历过的元素。当遍历到元素 \(\textit{nums}[i]\) 时,如果 \(\textit{nums}[i]\) 已经在哈希表 \(\textit{st}\) 中,那么说明我们需要移除 \(\textit{nums}[0..i]\) 的所有元素,需要的操作次数为 \(\left\lfloor \frac{i}{3} \right\rfloor + 1\)。否则,我们将 \(\textit{nums}[i]\) 加入哈希表 \(\textit{st}\) 中,并继续遍历下一个元素。

遍历结束后,如果没有找到重复的元素,那么数组中的元素已经互不相同,不需要进行任何操作,答案为 \(0\)

时间复杂度 \(O(n)\),空间复杂度 \(O(n)\)。其中 \(n\) 为数组 \(\textit{nums}\) 的长度。

1
2
3
4
5
6
7
8
class Solution:
    def minOperations(self, nums: List[int]) -> int:
        st = set()
        for i in range(len(nums) - 1, -1, -1):
            if nums[i] in st:
                return i // 3 + 1
            st.add(nums[i])
        return 0
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
class Solution {
    public int minOperations(int[] nums) {
        Set<Integer> st = new HashSet<>();
        for (int i = nums.length - 1; i >= 0; --i) {
            if (!st.add(nums[i])) {
                return i / 3 + 1;
            }
        }
        return 0;
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
class Solution {
public:
    int minOperations(vector<int>& nums) {
        unordered_set<int> st;
        for (int i = nums.size() - 1; ~i; --i) {
            if (st.contains(nums[i])) {
                return i / 3 + 1;
            }
            st.insert(nums[i]);
        }
        return 0;
    }
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
func minOperations(nums []int) int {
    st := make(map[int]struct{})
    for i := len(nums) - 1; i >= 0; i-- {
        if _, ok := st[nums[i]]; ok {
            return i/3 + 1
        }
        st[nums[i]] = struct{}{}
    }
    return 0
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
function minOperations(nums: number[]): number {
    const st = new Set<number>();
    for (let i = nums.length - 1; i >= 0; i--) {
        if (st.has(nums[i])) {
            return Math.floor(i / 3) + 1;
        }
        st.add(nums[i]);
    }
    return 0;
}

评论