這是我參與8月更文挑戰的第 9 天,活動詳情查看:8月更文挑戰web
給定一個非空整數數組,找到使全部數組元素相等所需的最小移動數,其中每次移動可將選定的一個元素加1或減1。 您能夠假設數組的長度最多爲10000。數組
輸入:[1,2,3]markdown
輸出:2svg
前言oop
各位同窗在作這道題的時候,可能會由於沒有思路,而後去評論區一看,各個題解一翻,會滿腦子問號,「爲啥?爲啥他們都說要用中位數來解?」,不知道爲何,反卻是用中位數的思路解了出來😶post
咱們先用一個小的測試樣例來進行推算測試
給出一個已經排好序的測試樣例 [0, 1, 2, 6, 8]ui
經過對數據的觀察,能夠得知,對首尾的兩個數 0,8 最小的移動次數就是在 [0, 8] 之間任意找一個數,他們的固定移動次數都是 8;若是嘗試在這個區間外找一個數來計算移動次數,如找 -1,則 0和8 的移動次數則爲 10url
同理,咱們對 1和6 進行最小次數移動的話, [1, 6] 中的任意數,他們固定移動 5次
最後剩下一個中間的數 2,不移動的話,最小次數爲 0
對這個參考數的選取則爲 [0, 8] ∪ [1, 6] ∪ [2] = 2
,他們的最小移動次數就是 8+5+0 = 13
上述思路能夠肯定,本題的核心點就是尋找中位數,上面分析的是奇數數組,下面分析偶數數組
示例: [0, 1, 2, 6]
一、在 [0, 6] 任意找一個數,固定最小次數 6 二、在 [1, 2] 任意找一個數,固定最小次數 1
中間數的選取條件爲 [0, 6] ∪ [1, 2] = [1, 2]
,即 1或2 都行,最小移動次數爲 6+1 = 7
上一步分析出來使用中位數是一種合適的解法,那麼,代碼很容易就出來了
left
指向 index=0
,right
指向 index=nums.length-1
貼上代碼
var minMoves2 = function(nums) {
nums.sort((a, b) => a - b);
let index = (nums.length - 1) / 2;
let center = Math.floor((nums[Math.floor(index)] + nums[Math.ceil(index)])) / 2;
return nums.reduce((a, b) => a + Math.abs(b - center), 0);
};
複製代碼