1. 题目与解析
给你一个非负整数数组 nums
。在一步操作中,你必须:
- 选出一个正整数
x
,x
需要小于或等于nums
中 最小 的 非零 元素。 nums
中的每个正整数都减去x
。
返回使 nums
中所有元素都等于 **0
需要的 最少 操作数。
输入: 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] 。
输入: nums = [0]
输出: 0
解释: nums 中的每个元素都已经是 0 ,所以不需要执行任何操作。
提示:
1 <= nums.length <= 100
0 <= nums[i] <= 100
第一种直观的方法可以通过排序来模拟来进行统计,从小到大输出所有的元素,每遍历到一个不同的元素,进行计数并且把现在的数字减到0,直到结束模拟。
另外,由于每次操作都将数组中的所有非零元素减少一个相同的值,因此数组中的相等元素减少到 000 的操作数相等,数组中的不相等元素减少到 000 的操作数不相等。
又由于使用贪心策略操作时,每次操作都会将数组中的最小非零元素减少到 000,因此最少操作数等于数组中的不同非零元素的个数。
使用哈希集合存储数组中的所有非零元素,则哈希集合的大小等于数组中的不同非零元素的个数,即为最少操作数。
需要注意的是,由于目标是将数组中的所有元素减少 000,如果数组中的一个元素已经是 000 则不需要对该元素执行操作,因此只需要考虑数组中的不同非零元素的个数。
2. 题解
小根堆:
class Solution {
public int minimumOperations(int[] nums) {
int ans = 0, flg = 0;
PriorityQueue<Integer> heap = new PriorityQueue<>();
for (int n: nums) {
heap.add(n);
}
while (!heap.isEmpty()) {
int i = heap.poll();
if (i <= flg) {
continue;
}
flg = i;
ans++;
}
return ans;
}
}
哈希表:
class Solution {
public int minimumOperations(int[] nums) {
Set<Integer> set = new HashSet<Integer>();
for (int num : nums) {
if (num > 0) { set.add(num); }
}
return set.size();
}
}