问题来源:
问题描述:
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]
思路与解决方案:
思路原作者:
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;
class Solution {
public:
int minMoves(vector<int>& nums) {
if(nums.size()<=1)
return 0;
long final=0,maxnum=nums[0],minnum=nums[0],sum=0;
for(int i=0;i<nums.size();++i)
{
sum+=nums[i];
if(nums[i]<minnum)
minnum=nums[i];
}
return sum-minnum*nums.size();
}
};
问题来源:
问题描述:
Given a non-empty integer array, find the minimum number of moves required to make all array elements equal, where a move is incrementing a selected element by 1 or decrementing a selected element by 1.
You may assume the array's length is at most 10,000.
Example:
Input: [1,2,3] Output: 2 Explanation: Only two moves are needed (remember each move increments or decrements one element): [1,2,3] => [2,2,3] => [2,2,2]
思路和解决方案:
![](https://discuss.leetcode.com/uploads/profile/50281-profileimg.jpg)
Suppose you have two endpoints A and B, when you want to find a point C that has minimum sum of distance between AC and BC, the point C will always between A and B. Draw a graph and you will understand it. Lets keep moving forward. After we locating the point C between A and B, we can define that
dis(AC) = c - a; dis(CB) = b - c;
sum = dis(AC) + dis(CB) = b - a.
b - a will be a constant value, given specific b and a. Thus there will be no difference between points among A and B.
In this problem, we set two boundaries, saying i and j, and we move the i and j to do the computation.
Hope it helps.
更严谨的证明:
![](https://discuss.leetcode.com/uploads/profile/43933-profileimg.png)
If the minimum number of moves makes all array entries {xi=1:N} to some value x, it can be proved that the optimal value x must be the median of {xi=1:N} (or any integer between the two central entries).
I have posted a rigorous math proof using triangle inequality here in problem "Best Meeting Point": https://discuss.leetcode.com/topic/53593/strict-mathematics-proof-to-minimize-sum_i-abs-x-x_i-using-triangle-inequality
int minMoves2(vector<int>& nums) {
sort(nums.begin(), nums.end()); int n = nums.size(), res = 0;
for (int i = 0; i < n/2; ++i) res += (nums[n-1-i]-nums[i]);
return res;
}
Problem: Given a sequence {xi=1:N}, prove that median x minimizes function f(x) := Σi=1:N | x-xi |.
Proof: Without losing generality, assume {xi=1:N} is sorted. Simply grouping the sum into pairs:
- f(x) = Σi=1:N/2 (| x-xi | + | x-xN+1-i |) + (N%2)*| x-xN/2+1 |.
Note that we don't have the last term if N is even since they are all grouped into pairs. I will explain why we need to (have to) group the sum in such a form later.
Using triangle inequality, |x-xi| + |x-xN+1-i| >= |xN+1-i - xi| = xN+1-i - xi, and the fact N%2 >= 0, so we can find a lower bound for f
- f(x) >= Σi=1:N/2 (xN+1-i - xi),
which means if we could actually pick an x to achieve this value, we find the optimal x!
Actually, inequality |x-xi| + |x-xN+1-i| >= |xN+1-i - xi| achieves equality if and only if x is in [xi, xN+1-i]. Since {xi=1:N} is increasing, closed interval sequence { [xi, xN+1-i] }i=1:N/2 is nested, and so they have non-empty common intersection [xN/2, xN-N/2+1]. This is critical, and this is why we need to design the grouping like this. Now it is trivial to see that picking any value in the intersection [xN/2, xN-N/2+1] will reach the minimum if N is even, and only x = xN/2+1 can reach the minimum if N is odd (since we also have to make |x-xN/2+1| zero).
解决方案:
class Solution {
public:
int minMoves2(vector<int>& nums) {
sort(nums.begin(),nums.end());
int i=0,j=nums.size()-1,Ret=0;
while(i<j)
{
Ret+=(nums[j--]-nums[i++]);
}
return Ret;
}
};