力扣刷題👊【462. 最少移動次數使數組元素相等 II】

這是我參與8月更文挑戰的第 9 天,活動詳情查看:8月更文挑戰web

題目連接

462. 最少移動次數使數組元素相等 IIapi

題目描述

給定一個非空整數數組,找到使全部數組元素相等所需的最小移動數,其中每次移動可將選定的一個元素加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

題目答案

上一步分析出來使用中位數是一種合適的解法,那麼,代碼很容易就出來了

  1. 對給定的數組進行排序
  2. 使用雙指針,left 指向 index=0right 指向 index=nums.length-1
  3. 對左右指針指向的數進行絕對值求差
  4. 左右指針往中心靠攏
  5. 處理左右指針在中心處的特殊狀況
    1. 左右指針重疊
    2. 左右指針相鄰

貼上代碼

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);
};
複製代碼
相關文章
相關標籤/搜索