题目
给你一个长度为 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;
}
}
评论区