LeetCode 1338.数组大小减半:贪心(有限删除出现次数多的)+哈希表

server/2024/12/16 23:02:49/

【LetMeFly】1338.数组大小减半:贪心(有限删除出现次数多的)+哈希表

力扣题目链接:https://leetcode.cn/problems/reduce-array-size-to-the-half/

给你一个整数数组 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},结果数组为空。

 

提示:

  • 1 <= arr.length <= 105
  • arr.length 为偶数
  • 1 <= arr[i] <= 105

解题方法:贪心 + 哈希表

当然是优先删除出现次数多的元素。怎么统计每个元素出现了多少次?使用一个哈希表即可。

之后对“每个出现次数”组成的数组排序,从出现次数最大的开始累加,直到和不小于 a r r 2 \frac{arr}{2} 2arr为止,所累加的数目即为答案。

  • 时间复杂度 O ( n log ⁡ n ) O(n\log n) O(nlogn),其中 n = l e n ( a r r ) n=len(arr) n=len(arr)
  • 空间复杂度 O ( n ) O(n) O(n)

AC代码

C++
class Solution {
public:int minSetSize(vector<int>& arr) {unordered_map<int, int> ma;for (int t : arr) {ma[t]++;}vector<int> times;for (auto&& [_, t] : ma) {times.push_back(t);}sort(times.begin(), times.end());int ans = 0;for (int cnt = 0, i = times.size() - 1; cnt < arr.size() / 2; ans++, i--) {cnt += times[i];}return ans;}
};
Python
from typing import List
from collections import Counterclass Solution:def minSetSize(self, arr: List[int]) -> int:ma = Counter(arr)times = [t for i, t in ma.items()]times.sort()ans, cnt, i = 0, 0, len(times) - 1while cnt < len(arr) // 2:ans += 1cnt += times[i]i -= 1return ans
Java
import java.util.Map;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;class Solution {public int minSetSize(int[] arr) {Map<Integer, Integer> ma = new HashMap<>();for (int t : arr) {ma.merge(t, 1, Integer::sum);}List<Integer> times = new ArrayList<>(ma.values());times.sort((a, b) -> b - a);int ans = 0;for (int cnt = 0, i = 0; cnt < arr.length / 2; ans++, i++) {cnt += times.get(i);}return ans;}
}
Go
package main
import "sort"func minSetSize(arr []int) (ans int) {ma := map[int]int{}for _, t := range arr {ma[t]++}var times []intfor _, t := range ma {times = append(times, t)}sort.Slice(times, func(i, j int) bool {return times[i] > times[j]})for cnt := 0; cnt < len(arr) / 2; ans++ {cnt += times[ans]}return
}

同步发文于CSDN和我的个人博客,原创不易,转载经作者同意后请附上原文链接哦~

Tisfy:https://letmefly.blog.csdn.net/article/details/144487651


http://www.ppmy.cn/server/150743.html

相关文章

微信小程序开发简易教程

微信小程序文件结构详解 1. 项目配置文件 project.config.json 项目的配置文件包含项目名称、appid、编译选项等配置示例&#xff1a; {"description": "项目配置文件","packOptions": {"ignore": []},"setting": {&quo…

Windows如何安装Php 7.4

一、进入官网&#xff0c;选择其他版本 https://windows.php.net/download/ 二、配置环境变量 将解压后的php 路径在系统环境变量中配置一下 cmd 后输入 php-v

JPG 转 PDF:免费好用的在线图片转 PDF 工具

JPG 转 PDF&#xff1a;免费好用的在线图片转 PDF 工具 在日常工作和生活中&#xff0c;我们经常需要将图片转换为 PDF 格式。无论是制作电子文档、准备演示材料&#xff0c;还是整理照片集&#xff0c;将图片转换为 PDF 都是一个常见的需求。今天为大家介绍一款完全免费、无需…

Dubbo生产者一次请求的过程 (Dubbo源码三)

Dubbo生产者一次请求的过程 &#xff08;Dubbo源码三&#xff09; https://www.bilibili.com/video/BV1FJSCY9E85 相较于Dubbo消费者一次请求的过程&#xff0c;生产者的流程相对复杂一些&#xff0c;主要是因为触发点不好找。 这篇文章通过解决以下三个问题来学习源码 请求的…

opencv——图片矫正

图像矫正 图像矫正的原理是透视变换&#xff0c;下面来介绍一下透视变换的概念。 听名字有点熟&#xff0c;我们在图像旋转里接触过仿射变换&#xff0c;知道仿射变换是把一个二维坐标系转换到另一个二维坐标系的过程&#xff0c;转换过程坐标点的相对位置和属性不发生变换&a…

mysql的执行计划分析和索引下推以及索引长度计算

1 执行计划介绍 执行计划&#xff08;Execution Plan&#xff09;是数据库查询优化的重要工具&#xff0c;用于展示数据库如何执行 SQL 查询的详细过程。它包含了查询操作的步骤、各个步骤的执行顺序、使用的索引、访问的表、连接方式、预计的成本等信息 可以显示SQL语句最终…

腾讯云海外服务器Window切换为linux系统(从Window DD 到 Linux)

腾讯云提示&#xff1a;不支持重装为该镜像&#xff0c;非中国大陆地域不支持Linux系统和Windows系统之间互转 买了腾讯云的海外服务器&#xff0c;重装系统的时候发现无法切换&#xff0c;直接dd到linux系统&#xff0c;以下是全过程。记录一下。 主要是用到一个开源项目&…

vue3 setup语法,子组件点击一个元素打印了这个元素的下标id,怎么传递给父组件,让父组件去使用

问&#xff1a; vue3 setup语法&#xff0c;子组件点击一个元素打印了这个元素的下标id&#xff0c;怎么传递给父组件&#xff0c;让父组件去使用 回答&#xff1a; 在 Vue 3 中&#xff0c;你可以使用 setup 语法糖和组合式 API 来实现子组件向父组件传递数据。具体来说&am…