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

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

給你一個長度爲 n 的整數數組 nums ,返回使所有數組元素相等需要的最少移動數。

在一步操作中,你可以使數組中的一個元素加 1 或者減 1 。

 

示例 1:

輸入:nums = [1,2,3]
輸出:2
解釋:
只需要兩步操作(每步操作指南使一個元素加 1 或減 1):
[1,2,3]  =>  [2,2,3]  =>  [2,2,2]
示例 2:

輸入:nums = [1,10,2,9]
輸出:16

來源:力扣(LeetCode)
鏈接:https://leetcode.cn/problems/minimum-moves-to-equal-array-elements-ii
著作權歸領釦網絡所有。商業轉載請聯繫官方授權,非商業轉載請註明出處

題目解析:

每次移動,可以將數組中的某一個數字加 1 或者減 1。求最少移動多少次,能讓數組中的數字都相等

分析
假設經過移動以後,所有的數字最終都等於 targettarget。

那麼這個 targettarget 的取值有兩種情況:在數組取值範圍外、在數組取值範圍內。

我們分情況討論。

情況一:targettarget 在數組取值範圍外

targettarget 在數組外的含義是 target > 數組最大值target>數組最大值或者 target < 數組最小值target<數組最小值。

假如 targettarget 在數組取值範圍之外,那麼把所有數字移動到 targettarget 一定比移動到邊界的移動次數更多!

以 nums = [1, 2, 3]nums=[1,2,3],target = 4target=4 爲例,說明爲什麼 targettarget 不能在數組之外,見圖:

因此,target一定在 nums 的最小值和最大值之間。

情況二:targettarget 在數組取值範圍內

當 targettarget在數組取值範圍內,那麼無論 targettarget 選擇何值,對於數組的最小值和最大值而言,它們移動到 targettarget 的次數之和一定是固定的!都等於 最大值 - 最小值最大值−最小值。

下圖以 nums = [1, 2, 3, 4, 5, 6]nums=[1,2,3,4,5,6],target = 4target=4 爲例,說明當 targettarget 取值在 [1,6][1,6] 範圍內,數字 11 與 數字 66 與 targettarget 的距離之和是定值 5;

然後,我們考慮去除 numsnums 的最大值、最小值以後的「子數組」,我們發現 targettarget 也需要選擇「子數組」範圍之內的數字。

因爲「情況一」中已經證明了,選擇「子數組」取值範圍外的數字不是最優。

如下圖所示, nums = [1, 2, 3, 4, 5, 6]nums=[1,2,3,4,5,6] ,當 targettarget 取 11 或者 66 時,對於子數組 [2,3,4,5][2,3,4,5] 不是最優:


綜上, targettarget 必須是不斷選擇 數組(以及子數組)最大值、最小值之間的數字,最終就是「中位數」。

根據上面的分析,可以得出結論:

  • 當數組的長度是偶數時,targettarget 可以選擇 22 箇中位數任何一個,總移動次數相等。
  • 當數組的長度是奇數時,中位數只有 11 個,因此 targettarget 選擇此中位數。

畫圖說明:

對於數組 nums = [1, 2, 3, 4, 5, 6]nums=[1,2,3,4,5,6] 而言,targettarget 一定選擇 33 或者 44。取兩者任何一個,結果是相等的。

當數組長度爲奇數時,target 一定選擇中位數。

當數組長度爲奇數時,target 一定選擇中位數。

代碼實現:

class Solution {
    public:
    int minMoves2(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        const int N = nums.size();
        int mid = nums[N / 2];
        int res = 0;
        for (int n : nums) {
            res += abs(n - mid);
        }
        return res;
    }
};

參考資料

1. 【負雪明燭】圖解算法:爲什麼選擇中位數

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章