462. 最少移动次数使数组元素相等 II

难度中等

给你一个长度为 n 的整数数组 nums ,返回使所有数组元素相等需要的最少移动数。

在一步操作中,你可以使数组中的一个元素加 1 或者减 1

示例 1:

输入:nums = [1,2,3]
输出:2
解释:
只需要两步操作(每步操作指南使一个元素加 1 或减 1):
[1,2,3]  =>  [2,2,3]  =>  [2,2,2]

示例 2:

输入:nums = [1,10,2,9]
输出:16

提示:

  • n == nums.length
  • 1 <= nums.length <= 10<sup>5</sup>
  • -10<sup>9</sup> <= nums[i] <= 10<sup>9</sup>

思想及代码:

Code1:超时

class Solution {
    public:
        int minMoves2(vector<int> &nums) {
            int cnt = 0;
            sort(nums.begin(), nums.end());
            int pos = nums.size() / 2 - 1;
            int i = 0, j = nums.size() - 1;
            while (i < j) {
                while (nums[i] < nums[pos]) {
                    nums[i]++;
                    cnt++;
                }
                i++;
                while (nums[j] > nums[pos]) {
                    nums[j]--;
                    cnt++;
                }
                j--;
            }
            return cnt;
        }
};

Code2:双指针,时间优化

class Solution {
    public:
        int minMoves2(vector<int> &nums) {
            int cnt = 0;
            sort(nums.begin(), nums.end());
            int pos = (nums.size()-1)/2;
            int i = 0, j = nums.size() - 1;
            while (i < j) {
                int cnt1 = nums[pos] - nums[i];
                int cnt2 = nums[j] - nums[pos];
                cnt += cnt1+cnt2;
                i++; 
                j--;
            }
            return cnt;
        }
};

Code3:用数学原理再优化

两数相减的差即为这两个数变为相等的加减次数

class Solution {
    public:
        int minMoves2(vector<int> &nums) {
            int cnt = 0;
            sort(nums.begin(), nums.end());
            int i = 0, j = nums.size() - 1;
            while (i < j) {
                cnt += nums[j] - nums[i];
                ++i;
                --j;
            }
            return cnt;
        }
};