一、题目描述(数组的改变、移动)
给你一个长度为 n 的整数数组,每次操作将会使 n - 1 个元素增加 1 。返回让数组所有元素相等的最小操作次数。
输入:nums = [1,2,3]
输出:3
解释:
只需要3次操作(注意每次操作会增加两个元素的值):
[1,2,3] => [2,3,3] => [3,4,3] => [4,4,4]
二、错误解法
找出最大的一个数,剩下的数加1,不断重复该操作,停止该操作的条件是加数后的所有数相等。
这样做会超出时间限制
public class Arrray_453 {
public static void main(String[] args) {
int[] nums = {1, 2, 3};
int n = nums.length;
boolean flag1 = true;
int temp = 0;//用于记录最小数的位置
int count = 0;//记录次数
while (flag1) {
//找出最大(最小是用来避免111这种情况)
int min = 65535;
int max = nums[0];
for (int i = 0; i < n; i++) {
if (nums[i] < min) {
min = nums[i];
}
if (nums[i] > max) {
max = nums[i];
temp = i;
}
}
if (min == max) {
return;//如果相等直接返回count
}
//进行加数
for (int j = 0; j < n; j++) {
if (j != temp) {
nums[j] = nums[j] + 1;
System.out.println(nums[j]);
}
}
//检查所有数都一样
int k=nums[0];
boolean flag2 = true;
while (flag2){
for (int t = 1; t < n; t++) {
if (k != nums[t]) {
flag2 = false;
break;
} else {
if (t == n - 1) {
flag1 = false;
flag2 = false;
}
}
}
}
count++;
}
System.out.println(count);
}
}
三、正确解法
其实按照题目的意思也可以理解为每次的操作都是使最大的那个数减1,显然对多个数操作比对一个数操作复杂。
所以我们在解题的时候就转换思想为最终目标是让所有的数等于最小的那个数,因此需要操作的次数也就为数组中每一个数与该数组最小值的差值之和
而且以最小值为标准的一个好处是最小值一直都是哪一个不会变,而最大值在经过某次的加1之后会改变这就导致每次都要去找最大值
class Solution {
public int minMoves(int[] nums) {
int n = nums.length;
int count=0;
int sum=0;
int min=nums[0];
for (int i = 0; i < n; i++) {
if (nums[i]<min){
min=nums[i];
}
}
// count=sum-min*n;//但是这样会有溢出问题
//所以计算每个数和min的差
for (int j = 0; j < n; j++) {
sum=nums[j]-min;
count+=sum;
}
return count;
}
}