Given a non-empty array of integers, return the k most frequent elements.
For example,
Given [1,1,1,2,2,3]
and k = 2, return [1,2]
.
Note:
- You may assume k is always valid, 1 ≤ k ≤ number of unique elements.
- Your algorithm's time complexity must be better than O(n log n), where n is the array's size.
先上hashmap进行频率统计,统计完生成频率数组。
对频率数组进行切分,找出频率数组中第K大的数记为A。
找出了频率数组中第K大的数A,倒回去在hashmap中检索频率大于等于A的数就是要求的,满足要求的数可能不止K个,取到K个就可以停止了。
public List<Integer> topKFrequent(int[] nums, int k)
{
ArrayList<Integer> retlist=new ArrayList<>();
int len=nums.length;
if(len<k)
return null;
HashMap<Integer, Integer> hashmap=new HashMap<>(len);
for(int num :nums)
if(!hashmap.containsKey(num))
hashmap.put(num, 1);
else {
hashmap.put(num,hashmap.get(num)+1);
}
int[] arr=new int[hashmap.size()];
int cnt=0;
for(int times : hashmap.values())
arr[cnt++]=times;
int kmax=findkmax(arr, 0, arr.length-1, arr.length-k);
for(int num :hashmap.keySet())
if(hashmap.get(num)>=kmax)
{
retlist.add(num);
if(retlist.size()==k)
break;
}
return retlist;
}
public int findkmax(int[] arr,int lo,int hi,int k)
{
if(lo==hi)
return arr[lo];
int index=partition(arr, lo, hi);
if(index==k)
return arr[index];
if(index>k)
return findkmax(arr, lo, index-1, k);
return findkmax(arr, index+1, hi,k);
}
public int partition(int[] a,int lo ,int hi)
{
int i=lo;
int j=hi+1;
int v=a[lo];
while(true)
{
while(a[++i]<v)
if(i==hi)
break;
while(v<a[--j])
if(j==lo)
break;
if(i>=j)
break;
swap(a, i, j);
}
swap(a, lo, j);
return j;
}
public void swap(int[] a,int i,int j)
{
int temp=a[i];
a[i]=a[j];
a[j]=temp;
}
---------------------------------------------------------------------------
Bucket Sort Solution
https://discuss.leetcode.com/topic/44237/java-o-n-solution-bucket-sort
public List<Integer> topKFrequent(int[] nums, int k) {
List<Integer>[] bucket = new List[nums.length + 1];
Map<Integer, Integer> frequencyMap = new HashMap<Integer, Integer>();
for (int n : nums) {
frequencyMap.put(n, frequencyMap.getOrDefault(n, 0) + 1);
}
for (int key : frequencyMap.keySet()) {
int frequency = frequencyMap.get(key);
if (bucket[frequency] == null) {
bucket[frequency] = new ArrayList<>();
}
bucket[frequency].add(key);
}
List<Integer> res = new ArrayList<>();
for(int pos = bucket.length-1; pos >= 0; pos--){
if(bucket[pos] != null){
for(int i = 0; i < bucket[pos].size() && res.size() < k; i++)
res.add(bucket[pos].get(i));
}
}
return res;
}
Heap Solution
public List<Integer> topKFrequent(int[] nums, int k) {
HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
for(int num: nums){
map.put(num, map.containsKey(num)? map.get(num) + 1 : 1);
}
PriorityQueue<Map.Entry<Integer, Integer>> pque =
new PriorityQueue<Map.Entry<Integer, Integer>>((o1, o2) -> o2.getValue() - o1.getValue());
pque.addAll(map.entrySet());
List<Integer> ret = new ArrayList<Integer>();
for(int i = 0; i < k; i++){
ret.add(pque.poll().getKey());
}
return ret;
}