[leetcode] 462. Minimum Moves to Equal Array Elements II 解题报告

46 篇文章 0 订阅

题目链接: https://leetcode.com/problems/minimum-moves-to-equal-array-elements-ii/

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]

思路: 一开始以为是找平均数然后求差值, wrong了一次之后感觉这题似曾相识, 记不得具体是哪题了, 好像是要找中位数的差值. 好吧, 暂时猜想为中位数, 那么还要证明其正确性.

考虑数组长度为奇数时, 如果最终的值小于中位数或者大于中位数, 则必然导致中位数那个数的移动. 举个例子, 数组长度为2n+1, 则中位数两边各有n个数, 如果左右两边移动到中位数的位置, 设左边所有数和中位数的差值和为x, 右边所有数和中位数的差值和为y, 则所有需要移动的次数为x+y. 但是如果最终的数不选择中位数, 比如选择median-1, 则左边的数移动到median-1需要至少(x-n)次移动(这里是至少, 有可能多于, 比如某个数大于median-1, 则需要向左移动), 而中位数右边的数移动到(median-1)则需要(y+n), 同时中位数还需移动一次. 这样总的移动次数就变成了 >= ((x-n) + (y+n) + 1). 显然比移动到中位数多移动了1. 同理选择一个大于中位数的值也一样.

再来考虑长度为偶数的情况, 这种情况下中位数为两个, 那么此时应该选择这两个的哪一个呢, 或者选其平均数? 答案是都可以! 我们可以先这样考虑, 让左边的中位数左边的数都移动到那个中位数的位置, 右边的的中位数右边的所有数都移动到右边中位数的位置, 这样所有的数就分成了两派, 隔海相望. 此时是你去找我还是我去找你, 或者两者都往中间走在任意位置相遇, 所消耗的代价都是一样的, 所以对于偶数长度的数组中位数同样成立! 证明完毕.

代码如下:

class Solution {
public:
    int minMoves2(vector<int>& nums) {
        int len = nums.size(), ans = 0;
        nth_element(nums.begin(), nums.begin()+len/2, nums.end());
        for(auto val: nums) ans += abs(val - nums[len/2]);
        return ans;
    }
};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值