leetcode[Minimum Moves to Equal Array Elements]

错误解法(解法可能有错,一种思路):

public class Solution {
	private boolean finish(int[] nums){
		if(nums.length == 0)
			return true;
		int temp = nums[0];
		for(int i = 1; i < nums.length; i++){
			if(nums[i] != temp)
				return false;
		}
		
		return true;
	}
	
    public int minMoves(int[] nums) {
    	int count = 0;
        while(!finish(nums)){//判断是否移动完成
        	Arrays.sort(nums);
        	//移动方法,排序,每次将前n-1个元素自增(总结规律发现这是最优的移动方式),也算是一种贪心,每次之后规模变化,问题形式不变
        	for(int i = 0; i < nums.length - 1; i++)
        		nums[i]++;
        	count++;
        }
        
        return count;
    }
}

正解:

public class Solution {
    public int minMoves(int[] nums) {
    	//这就是一个数学问题
    	//设sum是一开始数组nums中所有元素的和,minNum是一开始数组nums的最小元素,n是数组nums的长度
    	//假设在移动m次之后,数组中的所有元素相等,都为x
    	//那么根据等式恒等,得出:sum +  m*(n-1) = x*n
    	//m*(n-1)代表移动m次后增加的值,因为每次移动n-1个元素
    	//实际上,x = minNum + m
    	
    	//为什么x = minNum + m?
    	/*Let me explain why x = minNum + m
		  our goal is :increment minNum to be equal to maxNum
		  No matter how many add operations are executed,the goal won't change.
    	  Every time we do the add operation,the min number in the array must participate in.
    	  After an add operation,the minNum is still the min number(因为还有n-2个比它大的元素也增加了)
    	  So the minNum participate in every add operation
    	  So x = minNum + m
    	 */
    	
    	//将x = minNum + m代入sum +  m*(n-1) = x*n
    	//所以求解出 m = sum - minNum*n,这样求出的m是最小的,因为是按策略求得,知道相等时就结束了,之后还继续也可以再次相等,当然移动次数大于m
    	
    	/*Actually, this problem could be solved by dynamic programming:
			sort(nums)
			let s = move(nums, 0:k)
			then move(nums, 0:k+1) = s + abs(nums[k+1] - nums[k])
			return sum(s)

		In the end, you will find that this could written as sum(nums) - N * min;*/
    	
    	//开始将思路转化成代码
    	//最后要求解的就是m:m = sum - minNum*n
    	//先求出minNum
    	int minNum = nums[0];
    	for(int num : nums){
    		minNum = Math.min(minNum, num);//依次比较
    	}
    	//求出sum
    	int sum = 0;
    	for(int num : nums){
    		sum += num;
    	}
    	
    	int m = sum - minNum*nums.length;
    	
    	/*//m还可以这样求,之不管将上面的过程合到了一个循环中完成
    	int m = 0;
    	for(int num : nums){
    		m += num - minNum;
    	}*/
    	return m;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值