LeetCode——最小移動次數使陣列元素相等
阿新 • • 發佈:2020-08-03
Q:給定一個長度為 n 的非空整數陣列,找到讓陣列所有元素相等的最小移動次數。每次移動將會使 n - 1 個元素增加 1。
示例:
輸入:
[1,2,3]
輸出:
3
解釋:
只需要3次移動(注意每次移動會增加兩個元素的值):
[1,2,3] => [2,3,3] => [3,4,3] => [4,4,4]
A:
- 暴力法的基礎上,考慮到為了讓最小元素等於最大元素,至少需要加 k 次。在那之後,最大元素可能發生變化。因此,我們一次性增加增量 k=max-min,並將移動次數增加 k。然後,對整個陣列進行掃描,找到新的最大值和最小值,重複這一過程直到最大元素和最小元素相等。
要注意的是考慮可能最大值有多個
但超時了。
public int minMoves(int[] nums) { if (nums.length <= 1) return 0; int count = 0; while (true) { int minIndex = 0; int maxIndex = 0; for (int i = 0; i < nums.length; i++) { if (nums[i] < nums[minIndex]) minIndex = i; if (nums[i] > nums[maxIndex]) maxIndex = i; } int max = nums[maxIndex]; int min = nums[minIndex]; if (min == max) { break; } int temp = max - min; count += temp; for (int i = 0; i < nums.length; i++) { if (i != maxIndex) nums[i] += temp; } } return count; }
- 數學法
將除了一個元素之外的全部元素+1,等價於將該元素-1,因為我們只對元素的相對大小感興趣。因此,該問題簡化為需要進行的減法次數。顯然,我們只需要將所有的數都減到最小的數即可。為了找到答案,我們不需要真的操作這些元素。只需要\(moves = \sum_{i=0}^{n-1}(a[i]-min)\)即可
public class Solution { public int minMoves(int[] nums) { int moves = 0, min = Integer.MAX_VALUE; for (int i = 0; i < nums.length; i++) { min = Math.min(min, nums[i]); } for (int i = 0; i < nums.length; i++) { moves += nums[i] - min; } return moves; } }