LeetCode每日一题4.8

3396. 使数组元素互不相同所需的最少操作次数

LeetCode每日一题4.8_第1张图片

问题分析

题目要求通过移除数组的前缀元素,使得数组中的所有元素互不相同。每次操作可以移除数组的前 3 个元素(如果数组中元素少于 3 个,则移除所有剩余元素)。目标是找到使数组元素互不相同的最少操作次数。

思路

检查当前数组是否满足条件:
如果数组长度小于等于 1,直接返回操作次数,因为单个元素或空数组默认互不相同。
如果数组中的元素互不相同(即 len(set(nums)) == len(nums)),直接返回操作次数。
移除前 3 个元素:
如果数组长度大于等于 3,移除前 3 个元素。
如果数组长度小于 3,移除所有剩余元素。
循环执行上述步骤:
每次移除后,更新数组并检查是否满足条件。
如果满足条件,返回操作次数;否则继续移除。

代码

class Solution:
    def minimumOperations(self, nums: List[int]) -> int:
        operations = 0

        while True:
            # 如果数组长度小于等于 1,直接返回当前操作次数
            if len(nums) <= 1:
                return operations

            # 检查剩余数组是否元素互不相同
            if len(set(nums)) == len(nums):
                return operations

            # 移除前 3 个元素(或剩余的所有元素)
            nums = nums[3:] if len(nums) >= 3 else []
            operations += 1

复杂度分析

时间复杂度
每次移除操作:
每次循环都需要检查数组是否元素互不相同,最坏情况下需要遍历整个数组。
因此,总时间复杂度为 (O(n^2)),其中 (n) 是初始数组的长度。
空间复杂度
使用了一个集合 set(nums) 来检查数组是否元素互不相同,空间复杂度为 (O(n)),其中 (n) 是当前数组的长度。

学习

len(set(nums)) == len(nums)

无重复元素:集合自动去重,只保留唯一的元素。
无序性:集合中的元素没有固定的顺序。
支持快速查找:集合的底层实现基于哈希表,因此查找、添加和删除操作的时间复杂度均为 (O(1))(平均情况)。
具体行为
输入:一个列表 nums,例如 [1, 2, 3, 2, 3]。
输出:一个集合,其中包含 nums 中的所有唯一元素,例如 set([1, 2, 3, 2, 3]) 的结果是 {1, 2, 3}。

优化方法学习:

倒序遍历:
分析:
每次操作,移除的都是 nums 的开头的元素,或者说移除的是 nums 的前缀。

所以移除后,剩余的元素一定是 nums 的后缀。

所以本质上,我们要找的是 nums 的一个后缀,其中没有重复元素。

为了最小化操作次数,这个后缀越长越好。

所以问题相当于:

nums 的最长无重复元素后缀。
移除操作学习:
LeetCode每日一题4.8_第2张图片

class Solution:
    def minimumOperations(self, nums: List[int]) -> int:
        seen = set()
        for i in range(len(nums) - 1, -1, -1):
            x = nums[i]
            if x in seen:
                return i // 3 + 1
            seen.add(x)
        return 0

参考:灵茶山艾府
链接:https://leetcode.cn/problems/minimum-number-of-operations-to-make-elements-in-array-distinct/solutions/3027035/on-yi-ci-bian-li-jian-ji-xie-fa-pythonja-jgox/
来源:力扣(LeetCode)

你可能感兴趣的:(我的学习记录,leetcode)