地址:
力扣https://leetcode-cn.com/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},结果数组为空。 |
示例 3:
输入:arr = [1,9] 输出:1 |
示例 4:
输入:arr = [1000,1000,3,7] 输出:1 |
示例 5:
输入:arr = [1,2,3,4,5,6,7,8,9,10] 输出:5 |
提示:
1 <= arr.length <= 10^5 arr.length 为偶数 1 <= arr[i] <= 10^5 |
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/reduce-array-size-to-the-half
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路:
又是一道阅读理解题目
arr = [3,3,3,3,5,5,5,2,2,7]
大小为 2 的可行集合有 {3,5},{3,2},{5,2}。
最开始理解不到为什么是 2,{3,5} 得到 [2,2,7] , {3,2} 得到 [5,5,5,7],{5,2}得到[3,3,3,3,7]
这里面最小数组大小为 3,不为 2啊
再看,原来是求需要组成新数组的元素个数最小,上面3中组合都满足<=原始数组一半大小
那么,题目就很好解决了,统计所有元素个数,然后贪心下
计数数组可以参考:
排序算法之计数排序
方法一、计数数组
int cmp(const void *a, const void *b)
{
return *(int *)a - *(int *)b;
}
int minSetSize(int* arr, int arrSize){
int i;
int halfnum = arrSize / 2;
int retnum = 0;
int min = arr[0];
int max = arr[0];
for(i=0; i<arrSize; i++)
{
if(min > arr[i])
min = arr[i];
if(max < arr[i])
max = arr[i];
}
int offset = 0 - min;
int countLen = max - min + 1;
int *countArray = (int *)malloc(sizeof(int) * countLen);
for(i=0; i<countLen; i++)
{
countArray[i] = 0;
}
for(i=0; i<arrSize; i++)
{
countArray[arr[i]+offset]++;
}
qsort(countArray, countLen, sizeof(int), cmp);
i = countLen - 1;
while(halfnum && i < countLen)
{
if(halfnum <= countArray[i])
{
retnum++;
break;
}
else
{
retnum++;
halfnum -= countArray[i];
}
i--;
}
return retnum;
}