给你一个整数数组 nums
和一个整数 k
,请你返回其中出现频率前 k
高的元素。你可以按 任意顺序 返回答案。
// class Solution {
// public int[] topKFrequent(int[] nums, int k) {
// // 排序
// //
// int n = nums.length;
// int[] ans = new int[n - k + 1];
// int idx = 0;
// Arrays.sort(nums);
// for(int i = 0; i < n; i++){
// int num = nums[i];
// int cnt = 1;
// int j = i + 1;
// while(j < n && num == nums[j]) {
// cnt++;
// if(cnt >= k) {
// ans[idx++] = num;
// break;
// }
// j++;
// }
// i = j;
// }
// return ans;
// }
// }
// 左右指针
// class Solution{
// public int[] topKFrequent(int[] nums, int k){
// int n = nums.length;
// List<Integer> list = new ArrayList<>();
// // int[] ans = new int[n];
// Arrays.sort(nums);
// int l = 0, r = 0;
// int idx = 0;
// while(r < n){
// int cnt = 0;
// while(r < n && nums[l] == nums[r]){
// cnt++;
// r++;
// }
// if(cnt >= k){
// // ans[idx++] = nums[l];
// list.add(nums[l]);
// }
// l = r;
// }
// int[] ans = new int[list.size()];
// for(int num : list) ans[idx++] = num;
// // Integer[] ans = (int)list.toArray(new Integer[list.size()]);
// return ans;
// }
// }
// 理解错题意了。。。靠
// HashMap
// class Solution{
// public int[] topKFrequent(int[] nums, int k){
// // 使用map统计nums
// Map<Integer, Integer> map = new HashMap<>();
// for(int num : nums){
// if(map.containsKey(num)){
// map.put(num, map.get(num) + 1);
// } else {
// map.put(num, 1);
// }
// }
// //
// int[] ans = new int[k];
// int idx = 0;
// for(int i = 0; i < k; i++){
// int max = Integer.MIN_VALUE;
// // 遍历map
// int num = -1;
// for(Map.Entry<Integer, Integer> entry : map.entrySet()){
// if(entry.getValue() > max) {
// num = entry.getKey();
// max = entry.getValue();
// }
// }
// map.remove(num);
// ans[idx++] = num;
// }
// return ans;
// }
// }
//
class Solution{
public int[] topKFrequent(int[] nums, int k){
int n = nums.length;
Map<Integer, Integer> map = new HashMap<>();
for(int num : nums){
// if(map.containsKey(num)) map.put(num, map.get(num) + 1);
// else map.put(num, 1);
map.put(num, map.getOrDefault(num, 0) + 1);
}
// 我妄想用数组,代替桶。
// 再出现重复频率的数字情况,不能在一个数组位置存储多个元素
/*
int[] numss = new int[n + 1];
for(Map.Entry<Integer, Integer> entrySet : map.entrySet()){
numss[entrySet.getValue()] = entrySet.getKey();
}
int[] ans = new int[k];
int idx = n;
for(int i = 0; i < k; i++){
while(numss[idx] == 0) idx--;
ans[i] = numss[idx--];
}
return ans;
*/
// list类型的数组
List<Integer>[] list = new List[n + 1];
// 将value对应的下标,添加上key
for(Map.Entry<Integer, Integer> entrySet : map.entrySet()){
int idx = entrySet.getValue();
// 不判断是否为null就创建的话,可能会重复覆盖创建
if(list[idx] == null) list[idx] = new ArrayList();
list[idx].add(entrySet.getKey());
}
// // 从后向前,将list取出k个
// int[] ans = new int[k];
// for(i = 0; i < k; i++){
// }
List<Integer> ans = new ArrayList<>();
for(int i = n; i >= 0 && ans.size() < k; i--){
if(list[i] == null) continue;
ans.addAll(list[i]);
}
// int[] arr = ans.toArray();
return ans.stream().mapToInt(Integer::intValue).toArray();
}
}
优先队列,大顶堆、小顶堆。。。