1. 程式人生 > >110、最小移動次數使陣列元素相等

110、最小移動次數使陣列元素相等

給定一個長度為 n 的非空整數陣列,找到讓陣列所有元素相等的最小移動次數。每次移動可以使 n - 1 個元素增加 1。

示例:

輸入:
[1,2,3]

輸出:
3

解釋:
只需要3次移動(注意每次移動會增加兩個元素的值):

[1,2,3] => [2,3,3] => [3,4,3] => [4,4,4]

尷尬了,這樣的演算法肯定會超時啊,所以有些題目你需要將題目變個意思,或者利用歸納法得出一個比較簡單的解法,這樣就簡單了

class Solution {
    public int minMoves(int[] nums) {
    int count = 0;
		if(nums.length == 0 || nums.length == 1){
			return 0;
		}
		if(nums.length == 2){
			return nums[1] - nums[0] > 0? nums[1] - nums[0]:nums[0] - nums[1];
		}
		//Arrays.sort(nums);
		while (!isEqual(nums)) {
			Arrays.sort(nums);
			
			int tem = nums[nums.length - 1] - nums[nums.length - 2];
			int j = nums.length - 1;
			while (tem == 0) {
				tem = nums[j-1] - nums[j-2];
				j--;
				
			}
			//System.out.println(tem);
			count+= tem;
		
			for (int i = 0; i < nums.length-1; i++) {
				
				//	System.out.println(nums[i]+"自增啦");
					nums[i] +=tem;
					
			}
		}
		
		
		return count;
        
    }
	public static boolean  isEqual(int []nums){
		HashMap<Integer, Integer> map = new HashMap<>();
		for (int i = 0; i < nums.length; i++) {
			map.put(nums[i], map.getOrDefault(nums[i], 0)+1);
			
		}
		if(map.size() == 1){
			return true;
		}else {
			return false;
		}
		
		
		
	}
}

逆向思考,每次移動讓剩餘的n-1個數加1,相當於每次移動讓選定的那個數減1,
所以最少移動次數其實就是所有元素減去最小元素的和可以改成這樣的演算法,那樣就比較簡單了

class Solution {
    public int minMoves(int[] nums) {
         int min = Integer.MAX_VALUE;
        int ref = 0;
        for (int i = 0; i < nums.length; i++) {
            min = Integer.min(min, nums[i]);
        }
        for (int i = 0; i < nums.length; i++) {
            ref += nums[i]-min;
        }
        return ref;
    }
}

排名靠前的演算法

class Solution {
    public int minMoves(int[] nums) {
        if (nums == null || nums.length == 0) {
            return 0;
        }

        int min = Integer.MAX_VALUE;
        int res = 0;
        for (int i : nums) {
            if (i < min) {
                min = i;
            }
            res += i;
        }

        return res - min * nums.length;
    }
}