一、题目大意:
给定一个非空数组(长度为n),每次“移动”只能对数组中n-1个元素都加一,问经过多少次移动,数组的元素能完全一样
二、分析
1,正向理解:每次把最小的n-1个数加一,直到所有的都一样停止
2,反向理解:
首先,每次加一的元素肯定是数组中最小的n-1的元素
其次,把最小的n-1个元素都加1,相当于所有元素都加1,最大的元素减一,因为题目要求最后的元素值相同即可,所以所有元素加一操作完全可以去掉,即每一次的“移动”操作等价于把最大元素减一
再次,经过多次“移动”,必然能达到元素值完全相同,且最终状态为每个元素都等于初始数组的最小值,因为每次“移动”都是把最大值减一,只要数组中最大值不等于最小值,那么就会对最大值减一。
最后,移动的次数等于sum(nums)-min(nums)*len(nums)
三、代码
1,正向
public static int minMoves(int[] nums) {
int moves = 0;
int max = 0;
int maxIndex = 0;
while(true) {
Set<Integer> set = new HashSet<Integer>();
for(int i=0;i<nums.length;i++) {
set.add(nums[i]);
}
if(set.size() == 1) {//数组元素是否一致
return moves;
}else {
for(int i=0;i<nums.length;i++) {//找最大值
if(nums[i] > max) {
max = nums[i];
maxIndex = i;
}
}
for(int i=0;i<nums.length;i++) {//移动一次
if(i != maxIndex) {
nums[i]++;
}
}
moves++;
}
}
}
2,反向
public static int minMoves2(int[] nums) {
int sum = 0;
int min = Integer.MAX_VALUE;
for(int i=0;i<nums.length;i++) {
if(nums[i] < min) {
min = nums[i];
}
sum += nums[i];
}
return sum - min*nums.length;
}
3,python,反向
class Solution(object):
def minMoves(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
return sum(nums) - min(nums)*len(nums)