———————————————————————————————————————
题目描述
题目链接:leetcode 1481. 不同整数的最少数目
给你一个整数数组 arr 和一个整数 k 。现需要从数组中恰好移除 k 个元素,请找出移除后数组中不同整数的最少数目。
示例 1:
输入:arr = [5,5,4], k = 1
输出:1
解释:移除 1 个 4 ,数组中只剩下 5 一种整数。
示例 2:
输入:arr = [4,3,1,1,3,3,2], k = 3
输出:2
解释:先移除 4、2 ,然后再移除两个 1 中的任意 1 个或者三个 3 中的任意 1 个,最后剩下 1 和 3 两种整数。
提示:
1 <= arr.length <= 10^5
1 <= arr[i] <= 10^9
0 <= k <= arr.length
解题思路
思路:由贪心的思想可以想到:在移除元素的时候尽量移除出现次数少的整数,则留下来的不同整数就越少。
实现:定义一个结构体node(或类)记录arr中每个元素的值及其出现的次数,而每个元素的值和对应次数可以通过Map实现—和统计文本中单词数目的做法一致。接着依据元素出现的次数由小到大给node类型数组排序。最后从头遍历node类型数组,将头部的k个元素移除,剩下的就是留下的不同整数。
C++代码
const int N = 1e5+100;
typedef struct Node{
int number;
int f;
};
bool cmp(const Node &a,const Node &b){
return a.f < b.f;
}
class Solution {
public:
int findLeastNumOfUniqueInts(vector<int>& arr, int k) {
unordered_map<int,int>map;
Node nums[N];
for(auto &x : arr){
if(map.count(x)) map[x]++;
else map.insert(pair(x,1));
}
unordered_map<int,int>::iterator it;
int p=0;
for(it=map.begin();it != map.end();it++){
nums[p].number = it->first;
nums[p].f = it->second;
p++;
}
sort(nums,nums+p,cmp);
int res = p;
for(int i=0;i<p;i++){
if(k>=nums[i].f){
res--;
k-=nums[i].f;
}
else break;
}
return res;
}
};
Java代码
class node{
int x;
int f;
public node(int x,int f){
this.x = x;
this.f = f;
}
}
class cmp implements Comparator<node>{
@Override
public int compare(node a,node b) {
return a.f - b.f ;
}
}
class Solution {
public int findLeastNumOfUniqueInts(int[] arr, int k) {
HashMap<Integer, Integer> map = new HashMap<>();
for(int key : arr)
{
if(!map.containsKey(key)) {map.put(key, 1);}
else{
int f = map.get(key) + 1;
map.put(key, f);
}
}
ArrayList<node> list = new ArrayList<>();
int res = 0;
Set<Integer> set = map.keySet();//将key作为元素转存入一个set集合。
for ( Integer key : set)
{
node elem = new node(key,map.get(key));
list.add(elem);
res++;
}
Collections.sort(list,new cmp());
for(node elem : list)
{
if(k>=elem.f){ k-=elem.f; res--;}
else break;
}
return res;
}
}