LeetCode #1338 Reduce Array Size to The Half 將陣列的數量減至一半

英文原文如下

You are given an integer array arr. You can choose a set of integers and remove all the occurrences of these integers in the array.

Return the minimum size of the set so that at least half of the integers of the array are removed.

中文翻譯

給予你一個整數陣列 arr,你可以選擇一組整數集合,並刪除陣列中所有出現的他們。

回傳可以讓陣列至少一半的元素移除的最小集合數

範例及題目限制

先從第一個範例看起

選定了 {3,7} 這組集合,可以讓陣列中出現 3 或 7 都被移除掉

故剩下的 [5,5,5,2,2] 剛好數量為5,小於等於最初長度的一半

另外,限制中有提到陣列的長度為偶數


解題思路

C# 解決方案

方案1 – Dictionary + Linq

public class Solution {
    public int MinSetSize(int[] arr) {
        
        //0. half number
        int mid = arr.Length/2;
        
        //1. init dict
        Dictionary<int,int> dict =   new Dictionary<int,int>();
        
        foreach(var i in arr)
        {
            if (!dict.ContainsKey(i))
            {
                dict.Add(i, 1);
            }
            else
            {
                dict[i] = dict[i]+1;
            }
        }
        
        //2. check > order by dict value(count)
        var sortedDict = from entry in dict orderby entry.Value descending select entry.Value;
        
        int res = 0;
        foreach(var s in sortedDict)
        {
            if (s>mid)
            {                
                return res == 0 ? 1 : res+1;
            }
            else if (s<mid)
            {
                mid -= s;
                res +=1;
            }
            else    //s == mid
            {
                return res+1;
            }
        }
        
        return res;
        
    }
}

使用了Dictionary來儲存陣列出現的元素及其次數

另外使用了Linq來對Dictionary的value排序(降冪) ➡ value越高越好,因為希望用最少的整數集合

Java解決方案

方案1 -Map

class Solution {
    public int minSetSize(int[] arr) {
        //0. half number
        int mid = arr.length/2;
        
        //1. init map
        Map<Integer, Integer> map = new HashMap<Integer, Integer>();
        
        for(int i : arr)
        {
            if (!map.containsKey(i))
            {
                map.put(i, 1);
            }
            else
            {
                map.replace(i, map.get(i)+1); 
            }
        }
        
        //2. check > order by map value(count)
        Object[]vals = map.values().toArray();
        Arrays.sort(vals, Collections.reverseOrder());

            
        int res = 0;
        
        for(var v : vals)
        {
            int s= (Integer)v;
            
            if (s>mid)
            {                
                return res == 0 ? 1 : res+1;
            }
            else if (s<mid)
            {
                mid -= s;
                res +=1;
            }
            else    //s == mid
            {
                return res+1;
            }
        }
        
        return res;
        
    }
}

與C#相同,僅是將Dictionary用Map取代

Python3 解決方案

方案1

class Solution:
    def minSetSize(self, arr: List[int]) -> int:
        mid = len(arr)/2
        
        #init dictionary
        d = {} #dict
        
        for i in range(len(arr)):
            if(arr[i] in d):
                d[arr[i]] = d[arr[i]]+1
            else:
                d[arr[i]] = 1
                
        #2. check > order by dict value(count)
        d = dict(sorted(d.items(), key=lambda item: item[1], reverse=True))
        res = 0
        
        for s in d.values():
            if (s>mid):
                return 1 if res == 0 else res+1
            
            elif (s<mid):
                mid -= s
                res +=1
            
            else:    #s == mid
                return res+1
            
        return res

JavaScript 解決方案

方案1

/**
 * @param {number[]} arr
 * @return {number}
 */
var minSetSize = function(arr) {
    var mid = arr.length/2;
    
    //1. init dict
    var dict = { };
    
    arr.forEach(function(item){
        if(!(item in dict))
        {
            dict[item] = 1;
        }
        else
        {
            dict[item] = dict[item]+1;
        }
    });
    
    //2.order by values
    var k = Object.values(dict);
    k.sort();
    k = k.reverse();
    
    //3.find result
    var res = 0;
    for (let i = 0; i < k.length; i++) {
        const s = k[i];
        
        if (s>mid)
        {                
            return res == 0 ? 1 : res+1;
        }
        else if (s<mid)
        {
            mid -= s;
            res +=1;
        }
        else    //s == mid
        {
            return res+1;
        }
    }
    
    return res;;
};

結論

這一題以我的解答來說,麻煩的是對Dictionary或是Map的排序

通常來說這兩者都是無序的,都是按照Hash Table針對鍵值去進行映射

🧡如果這篇文章有幫上你的一點點忙,那是我的榮幸

🧡收藏文章或幫我分享,那都是對我的小小支持

✅如有任何疑問,歡迎透過留言或messenger讓我知道 !

題目連結 : Reduce Array Size to The Half – LeetCode

一些隨機文章

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *