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.
class Solution {
public:
struct numF{
int key;
int f;
} ;
void adjustUp(numF * A,int k){
if (k==1){
return;
}
else{
A[0] = A[k];
int i = k / 2;
while(i>0 && A[i].f<A[0].f){
A[k] = A[i];
k = i;
i = k / 2;
}
A[k] = A[0];
}
A[0].f = 0;
A[0].key = 0;
return;
}
void adjustDown(numF * A, int k, int heapSize){
A[0] = A[k];
for (int i = 2 * k; i <= heapSize; i *= 2){
if (i < heapSize && A[i].f < A[i + 1].f){
i++;
}
if (A[i].f <= A[0].f){
break;
}
else{
A[k] = A[i];
k = i;
}
}
A[k] = A[0];
return;
}
vector<int> topKFrequent(vector<int>& nums, int k) {
int vectorLength = nums.size();
/* get the size of the vector*/
map<int, int>countMap;
for (int i = 0; i<vectorLength; i++){
if (countMap.find(nums[i]) == countMap.end()){
countMap[nums[i]] = 1;
/* assigned a new element to the map*/
}
else{
countMap[nums[i]]++;
/* increase the frequency*/
}
}
/* build a map that contains all element an their frequency*/
int heapSize = countMap.size();
int heapEnd = 0;
numF * heap = new numF[heapSize+1];
memset(heap, 0, sizeof(numF)*(1+heapSize));
/* initialized a heap*/
for (map<int, int>::iterator it = countMap.begin();it != countMap.end();it++){
heapEnd++;
heap[heapEnd].f = it->second;
heap[heapEnd].key = it->first;
/* insert a value into the heap*/
adjustUp(heap, heapEnd);
/* insert elements and adjust position*/
}
/* build a heap*/
vector<int> results;
for (int i=0;i<k;i++){
results.push_back(heap[1].key);
heap[1]=heap[heapSize];
heapSize--;
adjustDown(heap,1,heapSize);
}
return results;
}
};
思路心得:
前半哈希后半堆排。代码太长思路很简单...晚点再解释