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

参考: ​​It is a math question​

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;
}
};