[Math_Medium]462. Minimum Moves to Equal Array Elements II
阿新 • • 發佈:2018-08-21
member 數值 sort 一個數 element ini 如果 str 順序 改良代碼:對於奇數個,中間那個數不用參與運算,即自己減自己為0;對於偶數個,中間那個數視為左邊的數,要參與運算;所以可以使用
原題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