侧边栏壁纸
博主头像
GabrielxD

列車は必ず次の駅へ。では舞台は?私たちは?

  • 累计撰写 471 篇文章
  • 累计创建 108 个标签
  • 累计收到 9 条评论

目 录CONTENT

文章目录

【数学, 排序, 双指针】最少移动次数使数组元素相等 II

GabrielxD
2022-05-19 / 0 评论 / 0 点赞 / 40 阅读 / 418 字 / 正在检测是否收录...

题目

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^5
  • -10^9 <= nums[i] <= 10^9

解题

方法一:排序 数学(找中位数)

思路

由题意,把数组排序后找到中位数然后把其他数与中位数的差全部加和即可(注意长度为偶数的数组有两个中位数)。

代码

class Solution {
    public int minMoves2(int[] nums) {
        Arrays.sort(nums);
        int len = nums.length;
        int midNum = nums[len / 2];
        int ans = 0;
        for (int num : nums) ans += Math.abs(num - midNum);
        if ((len & 1) == 0) {
            int leftMidNum = nums[len / 2 - 1];
            int ans1 = 0;
            for (int num : nums) ans1 += Math.abs(num - midNum);
            ans = Math.min(ans, ans1);
        }
        return ans;
    }
}

优化

好像当成一个中位数算也没差?

class Solution {
    public int minMoves2(int[] nums) {
        Arrays.sort(nums);
        int len = nums.length;
        int midNum = nums[len / 2];
        int ans = 0;
        for (int num : nums) ans += Math.abs(num - midNum);
        return ans;
    }
}

方法二:排序 双指针

思路

排序后使用对撞指针向中间移动的同时做差然后加和。

代码

class Solution {
    public int minMoves2(int[] nums) {
        Arrays.sort(nums);
        int left = 0, right = nums.length - 1;
        int ans = 0;
        while (left < right) ans += nums[right--] - nums[left++];
        return ans;
    }
}
0

评论区