列表

详情


1338. 数组大小减半

给你一个整数数组 arr。你可以从中选出一个整数集合,并删除这些整数在数组中的每次出现。

返回 至少 能删除数组中的一半整数的整数集合的最小大小。

 

示例 1:

输入:arr = [3,3,3,3,5,5,5,2,2,7]
输出:2
解释:选择 {3,7} 使得结果数组为 [5,5,5,2,2]、长度为 5(原数组长度的一半)。
大小为 2 的可行集合有 {3,5},{3,2},{5,2}。
选择 {2,7} 是不可行的,它的结果数组为 [3,3,3,3,5,5,5],新数组长度大于原数组的二分之一。

示例 2:

输入:arr = [7,7,7,7,7,7]
输出:1
解释:我们只能选择集合 {7},结果数组为空。

 

提示:

原站题解

去查看

上次编辑到这里,代码来自缓存 点击恢复默认模板
class Solution { public: int minSetSize(vector<int>& arr) { } };

golang 解法, 执行用时: 88 ms, 内存消耗: 11.9 MB, 提交时间: 2022-11-28 14:46:22

func minSetSize(arr []int) int {
	//统计每个数出现的次数
	countmap := make(map[int]int, 0)
	maxcount := 0
	for _, num := range arr {
		countmap[num]++
		if countmap[num] > maxcount {
			maxcount = countmap[num]
		}
	}
	//用桶排序出现次数
	bucket := make([]int, maxcount+1)
	for _, count := range countmap {
		bucket[count]++
	}

	n := (len(arr) - 1) / 2
	ret := 0
	for count := maxcount; count > 0; count-- {
		//v相同出现次数的数目,v*count相同出现次数的和
		v := bucket[count]
		//只有大于0才进
		if v ==0 {
			continue
		}
		if v*count < n {
			//需要去掉v个数,去掉数总和为v*count
			ret += v
			n -= v * count
		} else{
			//只需要去掉n/count+1个数,同时n小于0,结束
			ret += n /count + 1
			return ret
		}
	}
	return ret
}

golang 解法, 执行用时: 120 ms, 内存消耗: 19.2 MB, 提交时间: 2022-11-28 14:45:22

func minSetSize(arr []int) int {
	m := map[int]int{}
	for i := range arr {
		m[arr[i]]++
	}
	d := [][]int{}
	for k, v := range m {
		d = append(d, []int{k, v})
	}
	sort.Slice(d, func(i, j int) bool {
		return d[i][1] > d[j][1]
	})
	var r int
	l := len(arr) / 2
	var c int
	for i := range d {
		c += d[i][1]
		r++
		if c >= l {
			return r
		}
	}
    return 0
}

javascript 解法, 执行用时: 60 ms, 内存消耗: 53.2 MB, 提交时间: 2022-11-28 14:44:30

/**
 * @param {number[]} arr
 * @return {number}
 */
const minSetSize = arr => {
  const LEN = arr.length;
  if (LEN < 3) return 1;

  const max = Math.max(...arr);
  const freq = new Uint16Array(max + 1);
  let maxFreq = 0;
  for (const val of arr) ++freq[val] > maxFreq && (maxFreq = freq[val]);

  const freqBased = new Uint32Array(maxFreq + 1);
  for (const val of freq) ++freqBased[val];

  let step = 0;
  let sum = 0;
  for (let i = maxFreq; i >= 1; --i) {
    while (freqBased[i]--) {
      sum += i;
      ++step;
      if (sum >= LEN / 2) return step;
    }
  }
};

python3 解法, 执行用时: 104 ms, 内存消耗: 37 MB, 提交时间: 2022-11-28 14:43:28

class Solution:
    def minSetSize(self, arr: List[int]) -> int:
        freq = collections.Counter(arr)
        cnt, ans = 0, 0
        for num, occ in freq.most_common():
            cnt += occ
            ans += 1
            if cnt * 2 >= len(arr):
                break
        return ans

上一题