zoukankan      html  css  js  c++  java
  • [LeetCode] 1338. Reduce Array Size to The Half

    Given an 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.

    Example 1:

    Input: arr = [3,3,3,3,5,5,5,2,2,7]
    Output: 2
    Explanation: Choosing {3,7} will make the new array [5,5,5,2,2] which has size 5 (i.e equal to half of the size of the old array).
    Possible sets of size 2 are {3,5},{3,2},{5,2}.
    Choosing set {2,7} is not possible as it will make the new array [3,3,3,3,5,5,5] which has size greater than half of the size of the old array.
    

    Example 2:

    Input: arr = [7,7,7,7,7,7]
    Output: 1
    Explanation: The only possible set you can choose is {7}. This will make the new array empty.
    

    Example 3:

    Input: arr = [1,9]
    Output: 1
    

    Example 4:

    Input: arr = [1000,1000,3,7]
    Output: 1
    

    Example 5:

    Input: arr = [1,2,3,4,5,6,7,8,9,10]
    Output: 5

    Constraints:

    • 1 <= arr.length <= 10^5
    • arr.length is even.
    • 1 <= arr[i] <= 10^5

    数组大小减半。

    给你一个整数数组 arr。你可以从中选出一个整数集合,并删除这些整数在数组中的每次出现。返回 至少 能删除数组中的一半整数的整数集合的最小大小。

    我这里提供两种思路,一种利用到priority queue,一种是counting sort。

    首先是priority queue的做法。既然是试图删除数组中的一些unique的元素,使得删除的元素数量尽量大,但是这个集合尽量小,那么我们就需要统计每个元素在input数组中的出现次数。这里我们用hashmap统计,统计好的结果我们存入一个以priority queue表示的最大堆,堆顶是出现次数最多的数字。这样每次堆顶元素弹出的时候,他的出现次数是当前最多的,这样才能尽快地删除数组中一半整数。

    时间O(nlogn)

    空间O(n)

    Java实现

     1 class Solution {
     2     public int minSetSize(int[] arr) {
     3         HashMap<Integer, Integer> map = new HashMap<>();
     4         for (int num : arr) {
     5             map.put(num, map.getOrDefault(num, 0) + 1);
     6         }
     7         PriorityQueue<Integer> queue = new PriorityQueue<>((a, b) -> b - a);
     8         for (int num : map.keySet()) {
     9             queue.offer(map.get(num));
    10         }
    11         int count = 0;
    12         int sum = 0;
    13         while (!queue.isEmpty()) {
    14             sum += queue.poll();
    15             count++;
    16             if (sum >= arr.length / 2) {
    17                 return count;
    18             }
    19         }
    20         return -1;
    21     }
    22 }

    第二种方法是counting sort。首先我们看一下数组中出现的最大元素是什么,记录为max。之后我们创建一个长度为max + 1的数组count,记录所有元素的出现次数,并在记录完毕之后对其排序。当这个count数组有序之后,我们从元素最大的地方开始统计,计算一下每个元素的出现次数,当统计到数组中一半整数为止。

    时间O(nlogn)

    空间O(n)

    Java实现

     1 class Solution {
     2     public int minSetSize(int[] arr) {
     3         int max = Integer.MIN_VALUE;
     4         for (int num : arr) {
     5             max = Math.max(max, num);
     6         }
     7 
     8         int[] count = new int[max + 1];
     9         for (int num : arr) {
    10             count[num]++;
    11         }
    12         Arrays.sort(count);
    13         int half = arr.length / 2;
    14         int res = 0;
    15         for (int i = count.length - 1; i >= 0; i--) {
    16             half -= count[i];
    17             res++;
    18             if (half <= 0) {
    19                 return res;
    20             }
    21         }
    22         return arr.length;
    23     }
    24 }

    LeetCode 题目总结 

  • 相关阅读:
    Android实例-Delphi在运行时更改Android屏幕旋转(IOS也支持,不过我可没有苹果机,测试不了)
    delphi实现电脑屏幕旋转(电脑屏幕,不是手机屏幕)
    教程-关于escape和URI之间的不同!
    在Delphi中URLEncode文件名的最佳方法是什么?
    Delphi实现js中的escape()编码和unescape()解码
    面向对象: 接口与对象生存周期,接口自动释放
    问题-Delphi在做窗体派生时提示Resource TForm2 not found
    问题-delphi idTCPserver-Socket error问题详解
    delphi 求两个时间差
    Delphi 解决StrToDateTime()不是有效日期类型的问题
  • 原文地址:https://www.cnblogs.com/cnoodle/p/14317110.html
Copyright © 2011-2022 走看看