使数组中所有元素都等于零
难度:简单
给你一个非负整数数组 nums
。在一步操作中,你必须:
- 选出一个正整数
x
,x
需要小于或等于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 ,所以不需要执行任何操作。
排序 + 模拟
思路:
这道题要求计算将非负整数数组 nums \textit{nums} nums中的所有元素减少到 0 0 0 的最少操作数。用 m m m 表示数组 nums \textit{nums} nums中的最小非零元素,则可以选择不超过 m m m 的正整数 x x x,将数组中的每个非零元素减 x x x。为了使操作数最少,应选择 x = m x = m x=m,理由如下。
-
当选择 x = m x = m x=m 时,经过一次操作之后,数组中的所有元素 m m m 都变成 0 0 0,且其余的所有非零元素- 都减少 m m m。
-
当选择 x < m x < m x<m 时,经过一次操作之后,数组中的所有元素 m m m 在减少 x x x 之后仍大于 0 0 0,为了使数组中的最小非零元素变成 0 0 0,至少还需要一次操作,因此至少需要两次操作使数组中的所有元素 m m m 都变成 0 0 0,且其余的所有非零元素都减少 m m m。
由于当 x < m x < m x<m 时使元素 m m m 变成 0 0 0 的操作数大于当 x = m x = m x=m 时使元素 m m m 变成 0 0 0 的操作数,且两种方案中,使元素 m m m 变成 0 0 0 之后,剩余的最小非零元素相同(所有非零元素都减少 m m m),因此只有当 x = m x = m x=m 时才能使操作数最少。
根据上述分析,应使用贪心策略使操作数最少,贪心策略为每次选择数组中的最小非零元素作为 x x x,将数组中的每个非零元素减 x x x。
可以根据贪心策略模拟操作过程,计算最少操作数。
首先将数组 nums \textit{nums} nums按升序排序,然后从左到右遍历排序后的数组 nums \textit{nums} nums。对于每个遍历到的非零元素,该元素是数组中的最小非零元素,将该元素记为 x x x,将数组中的每个非零元素都减 x x x,将操作数加 1 1 1。遍历结束之后,即可得到最少操作数。
复杂度分析:
- 时间复杂度: O ( n 2 ) O(n^2) O(n2),其中 n n n 是数组 nums \textit{nums} nums 的长度。排序需要 O ( n log n ) O(n \log n) O(nlogn) 的时间,排序之后需要遍历数组一次,对于每个非零元素,将数组中的所有非零元素减去最小非零元素需要 O ( n ) O(n) O(n) 的时间,因此时间复杂度是 O ( n 2 ) O(n^2) O(n2)。
- 空间复杂度: O ( log n ) O(\log n) O(logn),其中 n n n 是数组 nums \textit{nums} nums的长度。排序需要 O ( log n ) O(\log n) O(logn) 的递归调用栈空间。
class Solution:
def minimumOperations(self, nums: List[int]) -> int:
nums = sorted(nums)
length, index, res = len(nums), 0, 0
while True:
while index != length and nums[index] == 0:
index += 1
if index == length:
return res
for i in range(length-1, index-1, -1):
nums[i] -= nums[index]
res += 1
哈希集合
思路:
由于每次操作都将数组中的所有非零元素减少一个相同的值,因此数组中的相等元素减少到 0 0 0 的操作数相等,数组中的不相等元素减少到 0 0 0 的操作数不相等。
又由于使用贪心策略操作时,每次操作都会将数组中的最小非零元素减少到 0 0 0,因此最少操作数等于数组中的不同非零元素的个数。
使用哈希集合存储数组中的所有非零元素,则哈希集合的大小等于数组中的不同非零元素的个数,即为最少操作数。
需要注意的是,由于目标是将数组中的所有元素减少 0 0 0,如果数组中的一个元素已经是 0 0 0 则不需要对该元素执行操作,因此只需要考虑数组中的不同非零元素的个数。
复杂度分析:
- 时间复杂度: O ( n ) O(n) O(n),其中 n n n 是数组 nums \textit{nums} nums的长度。需要遍历数组一次,每个非零元素加入哈希集合的时间是 O ( 1 ) O(1) O(1)。
- 空间复杂度: O ( n ) O(n) O(n),其中 n n n 是数组 nums \textit{nums} nums 的长度。哈希集合需要 O ( n ) O(n) O(n) 的空间。
class Solution:
def minimumOperations(self, nums: List[int]) -> int:
return len(set(nums) - {0})
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/make-array-zero-by-subtracting-equal-amounts