题目描述
时间复杂度小于O(n*logn),否则直接sort,再遍历就很轻松。 很有学习价值的题目,第一次使用了优先队列PriorityQueue。
思路 & 代码
首先遍历数组,用HashMap存储 元素值 - 频率 映射 然后维护一个容量为 k 的小顶堆(重写比较器,注意写法),遍历哈希表存入小顶堆中 接着把最终的小顶堆存入数组即可
class Solution {
public int [ ] topKFrequent ( int [ ] nums, int k) {
Map < Integer , Integer > hashmap = new HashMap ( ) ;
for ( int i = 0 ; i < nums. length; i++ ) {
if ( hashmap. containsKey ( nums[ i] ) ) {
hashmap. put ( nums[ i] , hashmap. get ( nums[ i] ) + 1 ) ;
}
else {
hashmap. put ( nums[ i] , 1 ) ;
}
}
PriorityQueue < Integer > pq = new PriorityQueue < > ( new Comparator < Integer > ( ) {
@Override
public int compare ( Integer key1, Integer key2) {
return hashmap. get ( key1) - hashmap. get ( key2) ;
}
} ) ;
for ( Integer key : hashmap. keySet ( ) ) {
if ( pq. size ( ) < k) {
pq. add ( key) ;
}
else if ( hashmap. get ( key) > hashmap. get ( pq. peek ( ) ) ) {
pq. remove ( ) ;
pq. add ( key) ;
}
}
int [ ] ans = new int [ k] ;
for ( int i = 0 ; i < k; i++ ) {
ans[ i] = pq. remove ( ) ;
}
return ans;
}
}
更新版:引入 stream 流 + Lambda
class Solution {
public int [ ] topKFrequent ( int [ ] nums, int k) {
Map < Integer , Integer > map = new HashMap < > ( ) ;
for ( int temp : nums) {
if ( map. containsKey ( temp) ) {
map. put ( temp, map. get ( temp) + 1 ) ;
}
else {
map. put ( temp, 1 ) ;
}
}
PriorityQueue < Integer > queue = new PriorityQueue < > (
( Integer a, Integer b) -> ( map. get ( a) - map. get ( b) ) ) ;
for ( Map. Entry < Integer , Integer > entry : map. entrySet ( ) ) {
if ( queue. size ( ) < k) {
queue. add ( entry. getKey ( ) ) ;
}
else if ( entry. getValue ( ) > map. get ( queue. peek ( ) ) ) {
queue. remove ( ) ;
queue. add ( entry. getKey ( ) ) ;
}
}
return queue. stream ( ) . mapToInt ( Integer :: valueOf ) . toArray ( ) ;
}
}