[Math_Medium]462. Minimum Moves to Equal Array Elements II
Posted qiulinzhang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Math_Medium]462. Minimum Moves to Equal Array Elements II相关的知识,希望对你有一定的参考价值。
原题462. Minimum Moves to Equal Array Elements II
题目大意:
给你一串数字,对于每个数字,一次性可以移动一步(数值增加1或者减小1),请问如何在最小的步伐数内使所有的数字都相等
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]
解题思路:
- 错误思路:我的第一想法是求出这一串数字的平均数,再用每一个数减去这个平均数,求和,即输出最短步伐,提交,WA,错误例子为[1,0,0,8,6],这里应设为1,而不是平均数
正确思路:我们先把这一列数按从小到大的顺序排序,把基准数k从最小数字开始,显然此时不是最优解,如果我们增加k,比k大的数字的步伐都会减1,比k小的数字的步伐都会加1,当k左右的数字一样多的时候,步伐最小。
k-a[1]+k-a[2]+k-a[3]+...+a[N-3]-k+a[N-2]-k+a[N-1]-k,当+k和-k的数目一样多的时候,k就会被抵消,这样就是后面的数减前面的数,这里要注意是奇数个还是偶数个代码1:
class Solution {
public:
int minMoves2(vector<int>& nums) {
sort(nums.begin(),nums.end());
int ans=0,mid=0;
if(nums.size()%2)
mid=(nums.size()+1)/2;
else
mid=nums.size()/2;
mid-=1;
for(int i=0;i<mid;i++)
ans-=(nums[i]);
for(int i=mid+1;i<nums.size();i++)
ans+=(nums[i]);
if(nums.size()%2==0)
ans-=nums[mid];
return ans;
}
};
改良代码:对于奇数个,中间那个数不用参与运算,即自己减自己为0;对于偶数个,中间那个数视为左边的数,要参与运算;所以可以使用(nums.size()+1)/2
,即若size为奇数,上面式子增加1,若为偶数,值不变,(相对于size/2)
class Solution{
public:
int minMoves2(vector<int>& nums)
{
sort(nums.begin(),nums.end());
int mid=nums.size()/2,ans=0;
for(int i=0;i<mid;i++)
ans-=nums[i];
for(int i=(nums.size()+1)/2;i<nums.size();i++)//使用(size()+1)/2,如果size是奇数,那么值会+1,即从下一项开始;如果是偶数,值不变,仍然当前项
ans+=nums[i];
return ans;
}
};
以上是关于[Math_Medium]462. Minimum Moves to Equal Array Elements II的主要内容,如果未能解决你的问题,请参考以下文章
462. Minimum Moves to Equal Array Elements II
LeetCode 462. Minimum Moves to Equal Array Elements II
462. Minimum Moves to Equal Array Elements II 最小移动到等数组元素II
462 Minimum Moves to Equal Array Elements II 最少移动次数使数组元素相等 II
Leetcode-462 Minimum Moves to Equal Array Elements II(最少移动次数使数组元素相等 II)