使数组中所有元素都等于零

标签: 贪心 数组 哈希表 排序 模拟 堆(优先队列)

难度: Easy

给你一个非负整数数组 nums 。在一步操作中,你必须:

  • 选出一个正整数 xx 需要小于或等于 nums最小非零 元素。
  • nums 中的每个正整数都减去 x

返回使 nums 中所有元素都等于 0 需要的 最少 操作数。

示例 1:

输入:nums = [1,5,0,3,5]
输出:3
解释:
第一步操作:选出 x = 1 ,之后 nums = [0,4,0,2,4] 。
第二步操作:选出 x = 2 ,之后 nums = [0,2,0,0,2] 。
第三步操作:选出 x = 2 ,之后 nums = [0,0,0,0,0] 。

示例 2:

输入:nums = [0]
输出:0
解释:nums 中的每个元素都已经是 0 ,所以不需要执行任何操作。

提示:

  • 1 <= nums.length <= 100
  • 0 <= nums[i] <= 100

Submission

运行时间: 26 ms

内存: 16.0 MB

class Solution:
    def minimumOperations(self, nums: List[int]) -> int:
        return len({x for x in nums if x})

Explain

此题解采用集合去重的思路来计算操作次数。首先使用集合来存储数组中所有非零的唯一值,由于集合的元性质自动去重,因此,集合的大小(即包含的不同非零元素的数量)直接反映了需要进行的操作次数。每次操作都是选择数组中最小的非零元素进行减法,直到所有非零元素均变为零。

时间复杂度: O(n)

空间复杂度: O(n)

class Solution:
    def minimumOperations(self, nums: List[int]) -> int:
        # 使用集合来存储所有非零元素,利用集合的去重性质
        return len({x for x in nums if x})  # 返回集合的大小,即不同非零元素的数量

Explore

在题解的算法中,数组中的零值对处理逻辑没有影响,因为算法只关注非零元素。使用集合存储元素时,通过条件表达式 'x for x in nums if x' 筛选出所有非零元素。这意味着零值不会被加入到集合中,也就不会影响集合的大小。因此,零值的存在不会增加操作次数,仅需关注非零元素的去重和计数。

题解中描述的算法仅计算将所有非零元素变为零的最小操作次数,而不需要实际进行每次操作。因此,算法中使用的集合无需维护元素的顺序。它只是用于确定有多少个不同的非零元素存在。如果需要实际执行这些操作,那么确实需要考虑元素的顺序,此时可能需要使用有序集合或在每次操作前对元素进行排序。

实际代码中,如果需要执行每次减法操作,需要首先确定集合中的最小值。这可以通过将集合转换成列表并排序来实现,或者使用如 Python 中的 `min()` 函数直接从集合中找到最小值。然而,题解中的 `minimumOperations` 方法只是计算需要的操作次数,而不是执行这些操作。因此,原题解中没有包含从集合中选取最小值的实际步骤。

题解中的方法不适用于动态变化的数组或实时数据流,因为它依赖于一次性读取和处理所有数据。对于动态数据,可以考虑使用动态数据结构,如哈希表,来实时更新和维护非零元素。每当有新元素加入时,可以更新哈希表,并适时调整计数。对于实时减少元素值到零的场景,可能需要更复杂的数据结构如平衡树或优先队列,以便能够高效地查询和更新最小元素。