原题:
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.
题意是给定体一个非空的整形数组和整数k,返回出现频率最高的k个元素
分析:既然是元素与其出现频率的对应关系,很快想到map类。
思路是遍历一遍数组,记录元素和其出现次数,元素存入key,出现次数存入value。然后对value进行从大到小排序,取前k个key即为所求。
需要进行排序,很自然想到TreeMap,但需注意的是TreeMap是对map中的key进行排序,而我们是对value进行排序,所以需要自己重写排序方法。
Java实现:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
public class Solution {
public List<Integer> topKFrequent(int[] nums, int k) {
List<Integer> result =new ArrayList<Integer>();
if(nums.length==0 || nums.length<k) return result;
Map<Integer,Integer> map = new HashMap<Integer,Integer>();
for (int i = 0; i < nums.length; i++) {//将数组元素放入map,对应的value是其出现的次数
int temp = nums[i];
if(map.containsKey(temp))
map.put(temp, map.get(temp)+1);
else
map.put(temp, 1);
}
List<Map.Entry<Integer, Integer>> list = new ArrayList<Map.Entry<Integer,Integer>>(map.entrySet());//map集合包装成list,对map中的value进行排序
Collections.sort(list,new Comparator<Map.Entry<Integer, Integer>>(){
@Override
public int compare(Entry<Integer, Integer> o1,
Entry<Integer, Integer> o2) {//对value从大到小排序
return o2.getValue()-o1.getValue();
}
});
for (int j=0;j<k;j++) {//取前k个
//System.out.println(list.get(j).getKey()+" : "+list.get(j).getValue());
result.add(list.get(j).getKey());
}
return result;
}
}
Python实现:
class Solution(object):
def topKFrequent(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: List[int]
"""
dict={}
result=[]
for i in nums:
if dict.has_key(i):
dict[i]+=1
else:
dict[i]=1
sortDict=sorted(dict.iteritems(),key=lambda d:d[1],reverse=True)#对value进行排序
for x in sortDict[:k]:#sortDict是一个list,每一个元素是排序后的元组,取前k个
result.append(x[0])#元组的第一个是dict中对应的key
return result