[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.

 

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: 16

 

Constraints:

  • n == nums.length

  • 1 <= nums.length <= 105

  • -109 <= nums[i] <= 109

一刷題解(中位數):

       這題給了一個無序的整數數組,然後要用最小的步數令數組的所有元素值統一。每一步可以使一個元素值+1/-1。這一題我最開始的思路是使所以元素都等於數組元素的平均值(nums.Sum / nums.Length),通過求得平均值與每個元素的差,得出總步數。然後驗證了一下題目給的兩個testcases({1, 2, 3}, {1, 10, 2, 9})都能通過,就想著沒問題了,結果在testcase { 1, 0, 0, 8, 6 }得出了錯誤的答案(expected 14, 我得出了16)。

        然後我調整了一下思路,既然是要令一個數組所有元素值統一,那就是代表它們要向某個值靠近。本來的求平均然後全部值向平均值靠近也是這個思路,但是我忘記了現在要求的是「最小步數」。所以如果我是以平均值為基準的話,很大機會全部元素都要向其靠攏,與其這樣,在當前數組元素中,選定一個元素,然後讓其他元素向該元素靠近想必能減少相當的步數。

        那怎樣的值才適合呢?既然是要讓所有值統一,那就是使小的值變大,使大的值變小,雙方同時朝對方趨近。那麼理所當然的,就是讓數組中元素值最接近中位數的值作為其他元素靠近的值了。

        首先先對數組進行排序,然後得到中間元素,然後得出其他元素與中間元素值的絕對差的總和就是答案。

public class Solution {
   public int MinMoves2(int[] nums) {
       Array.Sort(nums);

       int mid = nums[nums.Length / 2];
       int result = 0;
       for (int i = 0; i < nums.Length; i++)
      {
           result += Math.Abs(mid - nums[i]);
      }
       
       return result;
  }
}