Leetcode 1481. Least Number of Unique Integers after K Removals O(n)解法與易懂的O(nlogn)解法

自己的解法

  • 一個map記錄每個數字的頻率
  • 最小堆保存這些數據,再用k依次去減,看能去掉多少
  • 最終將map的大小減去去掉的數字即可得到答案
  • 時間複雜度O(nlogn)O(n\log n)
class Solution {
public:
    int findLeastNumOfUniqueInts(vector<int>& arr, int k) {
        unordered_map<int,int> mymap;
        int len = arr.size();
        
        for(int i=0; i<len; i++){
            mymap[arr[i]]++;
        }
        unordered_map<int, int>::iterator iter;
        priority_queue<int, vector<int>, greater<int>> minHeap;
        for(iter=mymap.begin();iter!=mymap.end();iter++){
            minHeap.push(iter->second);
        }
        int del = 0;
        while(k-minHeap.top()>=0){
            k-=minHeap.top();
            minHeap.pop();
            del++;
        }

        return mymap.size()-del;
    }
};

時間複雜度爲O(n)O(n)的方法

  • 依舊是map記錄每個元素的頻次。
    • 比如原始數據[1,1,2,2,3,3,3],k=4
    • 計算得到{1:2, 2:2, 3:3}
  • 對這些頻次再用map記錄,即“頻次的頻次”
    • 接着上面的例子 {2:2, 3:1}
  • 刪除元素的話,就直接按照所有可能的頻次,由低到高開始找,刪除。從最小的,即頻次爲1的元素開始刪除(先不管有沒有頻次爲1的)。然後一直到頻次最大的數字,即arr.size(可能也不存在),依次遍歷刪除即可。
    • 還拿上面的例子,如果找到一個,比如頻次爲2,發現頻次2它的頻次也是2,即arr中有兩個數字的頻次都是2。
    • k減去這兩個數x它們的頻次,即k-22,得到還可以減的量是4-22=0
    • 總的數字種類也-2,即去掉了2不同的數,還剩{3,3,3}
    • 再這樣循環下去,發現k不夠減了,則k整除當前頻次,看看能減多少減多少。舉另一個例子,與之前情況相同但k=3,那麼k=3減不了2*2,即去掉兩個不同的數,因此k可以減掉其中一個,即k//2=1(整除),具體代碼如下
def findLeastNumOfUniqueInts(self, arr: List[int], k: int) -> int:
    c = Counter(arr)
    cnt, remaining = Counter(c.values()), len(c)
    for key in range(1, len(arr) + 1):
        if k >= key * cnt[key]:
            k -= key * cnt[key]
            remaining -= cnt[key]
        else:
            return remaining - k // key
    return remaining

參考

Leetcode Discuss

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