原题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;
}
};
原文地址:https://www.cnblogs.com/qiulinzhang/p/9514357.html
时间: 2024-11-06 09:39:41