[LeetCode] 462. 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]

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

题意跟版本一很接近,但是这次并不是将所有的数字都往最大值靠拢,这个题考的是问最少操作多少次可以使所有数字相同,而且这个题的操作次数是针对每一个数字而言的,也就是说,每一个数字动一次,就是一次操作。

思路是找到数组的中位数,然后每个数字和中位数的差值就是操作次数。最后要求的结果就是每个数字的操作次数的累加和。既然是求中位数,比较直观的思路就是用Arrays.sort()先排序,找到数组中间的数字,或者是用快速排序找。就这道题的test case而言,前者更快。

时间O(nlogn), worse case is O(n^2)

空间O(1)

Java函数排序

 1 class Solution {
 2     public int minMoves2(int[] nums) {
 3         Arrays.sort(nums);
 4         int res = 0;
 5         int mid = nums[nums.length / 2];
 6         for (int num : nums) {
 7             res += Math.abs(num - mid);
 8         }
 9         return res;
10     }
11 }

 

快速排序

 1 class Solution {
 2     public int minMoves2(int[] nums) {
 3         int res = 0;
 4         int median = findKthLargest(nums, nums.length / 2 + 1);
 5         for (int num : nums) {
 6             res += Math.abs(median - num);
 7         }
 8         return res;
 9     }
10 
11     private int findKthLargest(int[] nums, int k) {
12         if (nums == null || nums.length == 0) {
13             return 0;
14         }
15         int left = 0;
16         int right = nums.length - 1;
17         while (true) {
18             int pos = partition(nums, left, right);
19             if (pos + 1 == k) {
20                 return nums[pos];
21             } else if (pos + 1 > k) {
22                 right = pos - 1;
23             } else {
24                 left = pos + 1;
25             }
26         }
27     }
28 
29     private int partition(int[] nums, int left, int right) {
30         int pivot = nums[left];
31         int l = left + 1;
32         int r = right;
33         while (l <= r) {
34             if (nums[l] < pivot && nums[r] > pivot) {
35                 swap(nums, l++, r--);
36             }
37             if (nums[l] >= pivot) {
38                 l++;
39             }
40             if (nums[r] <= pivot) {
41                 r--;
42             }
43         }
44         swap(nums, left, r);
45         return r;
46     }
47 
48     private void swap(int[] nums, int i, int j) {
49         int temp = nums[i];
50         nums[i] = nums[j];
51         nums[j] = temp;
52     }
53 }

 

LeetCode 题目总结

上一篇:1608. Special Array With X Elements Greater Than or Equal X


下一篇:JDK源码分析-CopyOnWriteArrayList