使數組唯一的最小增量--數學思維的運用

0x01.問題

給定整數數組 A,每次 move 操作將會選擇任意 A[i],並將其遞增 1
返回使 A 中的每個值都是唯一的最少操作次數。
輸入示例:[3,2,1,2,1,7]
輸出示例:6
解釋:經過 6 次 move 操作,數組將變爲 [3, 4, 1, 2, 5, 7]。
提示:0 <= A.length <= 40000 0 <= A[i] < 40000

C++函數形式爲      int minIncrementForUnique(vector<int>& A)

0x02.簡要分析

剛看到這個問題,肯定有點懵,因爲假如有相同的就加1的話,加1之後還可能與其它的數相同,繼續加,依然有可能在哪個角落有一個數就重複了,所以,這樣單純的掃描數組,看起來可行型不大。

困擾我們的問題主要是什麼呢?

就是,你不知道加完之後,哪個數會和這個數相同,要是我們能把相同的找出來就好了。

於是,思路來了,排序!!!

排序後,相同的肯定都在一起,如果加1,也可以根據下一個數來判斷是否衝突,這樣,這個麻煩的問題就解決了,然後,我們仔細思考一下具體思路:

排序後,如果A[i]==A[i-1],說明這裏重複了,那麼最簡單的辦法就是A[i]+1

如果A[i]<A[i-1]呢?爲什麼,會出現這個情況呢,因爲在前面相等的條件下,前面的數可能變大了,那麼這個時候最好的辦法還是A[i]=A[i-1]+1,操作數就是A[i-1]-A[i]+1

爲什麼我們要說最簡單的方法就是保持後一個比前一個大呢?

因爲對於一個數組來說,全部不重複的理想條件就是後一個剛好比前一個大1,我們的目的就是創造這個理想條件。

注意:

  • 其實源數組的值其實是在不斷的被改變的,這樣,我們就可以保證不重複了。
  • 不要輕易的去排序,排序的目的一定是排完序後,可以更加方便的解決問題,不然反而會造成時間的浪費。
  • 默認是升序,C++底層實現是插入排序和快速排序搭配使用。

0x03.解決代碼–排序後解決

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

ATFWUS --Writing By 2020–03–22

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