/*453、最小操作次数使数组元素相等*/
/*思路一:
* 逆向思维,因为每次使n-1个数增加相当于一个数1个数相对减小最终所有元素相等,那么我们就可以每次将数组中最大的数减一,
* 这样数组中除最小数外的所有数都有可能轮到自己是最大值,所以只需要将所有除最小值外的数减去最小值再加起来就是要执行的次数了
* */
public int minMoves(int[] nums) {
int min = Arrays.stream(nums).min().getAsInt();
int res = 0;
for (int num : nums) {
if (num > min) res += num - min;
}
return res;
}
/*665、非递减数列*/
/*思路一:
* 如果x[i]大于x[i+1]那么肯定要改两者中的一个来维持非递减,重点是需要改哪个
* 需要看x[i-1]和x[i+1]即l和r,如果l>r,比如3,4,1那么别无选择只能改1即nums[i+1]
* 如果l<r比如3,5,4那么我们这时候既可以改4为6也可以改5为3,选哪种呢,因为我们后面的数字还可能为5,就是3,5,4,5
* 这时如果改4为6那么6>5必定判定为false,但是是可以为true的,就是该5为4,所以l<=r的情况可以选择将中间数即nums[i]改为和左边或右边相等
* 遍历过程中要判断是否交换次数超过1,是则返回false
* */
/*通过*/
public boolean checkPossibility(int[] nums) {
int cnt = 0;
if (nums.length == 1) return true;
if (nums[0] > nums[1]) {
cnt++;
nums[0] = nums[1];
}
for (int i = 1; i < nums.length - 1; i++) {
if (nums[i] > nums[i + 1]) {
cnt++;
if (nums[i - 1] > nums[i + 1]) {
nums[i + 1] = nums[i];
} else {
nums[i] = nums[i + 1];
}
}
if (cnt > 1) return false;
}
return true;
}
/*283、移动零*/
/*思路一:双指针,慢指针总是指向0,快指针若不是零则与慢指针交换*/
/*通过*/
public void moveZeroes(int[] nums) {
int n = nums.length;
int l = 0, r = 0;
while (r < n) {
if (nums[r] != 0) {
int tmp = nums[r];
nums[r] = 0;
nums[l] = tmp;
}
if (nums[l] != 0) l++;
r++;
}
}