[LeetCode] 462. Minimum Moves to Equal Array Elements II

Given an integer array nums of size n, return the minimum number of moves required to make all array elements equal.

In one move, you can increment or decrement an element of the array by 1.

Test cases are designed so that the answer will fit in a 32-bit integer.

Example 1:

Input: nums = [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]

Example 2:

Input: nums = [1,10,2,9]
Output: 1 

Constraints:

  • n == nums.length
  • 1 <= nums.length <= 105
  • -109 <= nums[i] <= 109

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

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

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

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/minimum-moves-to-equal-array-elements-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

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

思路是找到数组的中位数,然后每个数字和中位数的差值就是操作次数。最后要求的结果就是每个数字的操作次数的累加和。既然是求中位数,比较直观的思路就是用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 题目总结

posted @ 2020-09-04 05:38  CNoodle  阅读(319)  评论(0编辑  收藏  举报