大佬,牛!!!
- 题目:就是给你一个数组,然后要求每个数都可以+1或者-1,问如何让这个数组变成只有数的数组,然后并且使得我们移动的次数最小。
- 我的思路:找到那个目标值,也就是我们要将数组中的内容变成的值,我以为平均值差不多就是我们要变成的那个数,然是错了,应该是中位数。
- 大佬的思路:我们需要让所有的数变到中位数,然后再计算次数即可,这个数就是中位数。结论是:所有数与中位数的绝对差之和最小。
- 证明:首先,给定一个从小到大的数列x1,x2,……,xn,设x是从x1到xn与其绝对差之和最小的数,则显然x位于x1与xn之间。那么,由于x1,xn与它们之间的任意一点的距离之和都相等,且都等于xn-x1,因此接下来可以不考虑x1与xn,而考虑剩下的从x2到x[n-1]的数,同样显然有x必然位于x2和x[n-1]之间,依次类推,最后得出的结论是x就是该数列中间的那个数,或者是中间的那两个数之一,而这个数就是中位数。
- 证明链接:虽然LeetCode也给出了证明,但是我参考的是这个链接。
- 技巧:主要是需要知道这个数学知识。真的是数学很重要啊。哎!!!
java代码
class Solution {
public int minMoves2(int[] nums) {
Arrays.sort(nums);
int ans = 0;
int len = nums.length;
int mid = nums[len / 2];
for (int i = 0; i < len; i++) {
ans += Math.abs(nums[i] - mid);
}
return ans;
}
}
- 总结:题目其实不难理解,主要是数学知识比较匮乏。此外,这里的时间复杂度主要再排序上,所以官方还有另外一种解法,应该是不排序,就找到中位数吧,没有仔细研究。