给你一个非负整数数组 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 ,所以不需要执行任何操作。
解题思路:
- 方法一:哈希集合
每次操作都是将数组中所有非零元素减去一个相同值,因此数组中的相同元素减少的到零的操作数相等,数组中不同元素减少到零的操作数不相等。
由于贪心策略操作时,每次都会将数组中的最小非零元素减少到0,因此最少操作数为数组中不同非零元素的个数。
代码:
class Solution {
public int minimumOperations(int[] nums) {
Set<Integer> set=new HashSet<>();
for(int num:nums){
if(num>0){
set.add(num);
}
}
return set.size();
}
}
- 方法二:排序+模拟
先将数组排序,然后找到数组中第一个非零的数,将数组中每一个非零整数减去该数,如此循环得到最终的操作数。
代码:
class Solution {
public int minimumOperations(int[] nums) {
int sum=0;
Arrays.sort(nums);
int len=nums.length;
for(int i=0;i<len;i++){
if(nums[i]>0){
sub(nums,nums[i],i);
sum++;
}
}
return sum;
}
public void sub(int nums[],int num,int i){
int len1=nums.length;
for(int j=i;j<len1;j++){
nums[j]-=num;
}
}
}