【LeetCode每日一題】使數組唯一的最小增量

給定整數數組 A,每次 move 操作將會選擇任意 A[i],並將其遞增 1。

返回使 A 中的每個值都是唯一的最少操作次數。

示例 1:

輸入:[1,2,2]
輸出:1
解釋:經過一次 move 操作,數組將變爲 [1, 2, 3]。
示例 2:

輸入:[3,2,1,2,1,7]
輸出:6
解釋:經過 6 次 move 操作,數組將變爲 [3, 4, 1, 2, 5, 7]。
可以看出 5 次或 5 次以下的 move 操作是不能讓數組的每個值唯一的。
提示:

0 <= A.length <= 40000
0 <= A[i] < 40000

來源:力扣(LeetCode)

C++1 先排序後累計

先對數組進行從小到大的排序,然後依次判斷後一個元素如果小於等於前一個,則將後面的元素變爲前一個元素+1大小,將二者的差累加起來,到最後一個元素後則算出最小的move操作。

class Solution {
public:
    int minIncrementForUnique(vector<int>& A) {
        if(A.size() == 0) return 0;
        sort(A.begin(),A.end());
        int move = 0;
        for(int i=1;i<A.size();i++){
            if(A[i] <= A[i-1]){
                move += A[i-1]+1-A[i];
                A[i] = A[i-1]+1;
            }
        }
        return move;
    }
};

C++2 計數

首先統計出每個數出現的次數,然後從小到大遍歷每個數 x:
如果 x 出現了兩次以上,就將額外出現的數記錄累加;
如果 x 沒有出現過,那麼在記錄下來的數中選取一個 v,將它增加到 x,需要進行的操作次數爲 x - v。
還是以 [1, 1, 1, 1, 3, 5] 爲例,當我們發現有 3 個重複的 1 時,我們先將操作次數減去 1 + 1 + 1。接下來,當我們發現 2,4 和 6 都沒有出現過時,我們依次將操作次數增加 2,4 和 6。

注意事項

雖然 A[i] 的範圍爲 [0, 40000),但我們有可能會將數據遞增到 40000 的兩倍 80000。這是因爲在最壞情況下,數組 A 中有 40000 個 40000,這樣要使得數組值唯一,需要將其遞增爲 [40000, 40001, …, 79999],因此用來統計的數組需要開到 80000。

class Solution {
public:
    int minIncrementForUnique(vector<int>& A) {
        int cnt[80000] = { 0 };
        for (int x: A) cnt[x]++;

        int ans = 0, taken = 0;

        for (int x = 0; x < 80000; ++x) {
            if (cnt[x] >= 2) {
                taken += cnt[x] - 1;
                ans -= x * (cnt[x] - 1);
            }
            else if (taken > 0 && cnt[x] == 0) {
                taken--;
                ans += x;
            }
        }

        return ans;
    }
};

方法二來源:
作者:LeetCode-Solution
鏈接:https://leetcode-cn.com/problems/minimum-increment-to-make-array-unique/solution/shi-shu-zu-wei-yi-de-zui-xiao-zeng-liang-by-

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