453. Minimum Moves to Equal Array Elements*
https://leetcode.com/problems/minimum-moves-to-equal-array-elements/
题目描述
Given a non-empty integer array of size n
, find the minimum number of moves required to make all array elements equal, where a move is incrementing n - 1
elements by 1
.
Example:
Input:
[1,2,3]
Output:
3
Explanation:
Only three moves are needed (remember each move increments two elements):
[1,2,3] => [2,3,3] => [3,4,3] => [4,4,4]
C++ 实现 1
let’s define sum
as the sum of all the numbers, before any moves; minNum
as the min number int the list; n
is the length of the list;
After, say m
moves, we get all the numbers as x , and we will get the following equation
sum + m * (n - 1) = x * n
and actually,
x = minNum + m
and finally, we will get
sum - minNum * n = m
So, it is clear and easy now.
也就是说, 必须注意到, 数组中的最小值 minNum
在经过 m
次变化之后的值为 minNum + m
, 并且等于其他值 x = minNum + m
, 此时总和一方面可以通过初始的 sum
加上 m * (n - 1)
(每次都是剩下的 n - 1
个元素加 1) 计算, 或者通过最终数组中所有值都相等进行计算 n * x
, 那么可以得到公式 m = sum - minNum * n
.
下面代码中 sum
设置为 long long
是为了避免 [1, INT32_MAX]
这种极端情况, 注意求和的时候直接使用
std::accumulate(nums.begin(), nums.end(), 0)
是会报错的.
class Solution {
public:
int minMoves(vector<int>& nums) {
long long sum = 0;
for (int i = 0; i < nums.size(); ++ i)
sum += nums[i];
int imin = *std::min_element(nums.begin(), nums.end());
return sum - imin * nums.size();
}
};
C++ 实现 2
或者这样也行, 避免数值过大的极端情况.
class Solution {
public:
int minMoves(vector<int>& nums) {
int res=0,minelement=*min_element(nums.begin(), nums.end());
for(int i:nums)res+=i-minelement;
return res;
}
};