leetcode 347. Top K Frequent Elements

257 篇文章 17 订阅

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.
这一题我的思路就是用一个map统计每个元素出现的频率,再使用bucket sort对频率排序。

package leetcode;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class Top_K_Frequent_Elements_347 {

	public List<Integer> topKFrequent(int[] nums, int k) {
		List<Integer> result=new ArrayList<Integer>();
		HashMap<Integer, Integer> num_frequency=new HashMap<Integer, Integer>();
		int maxFrequency=0;
		for(int i=0;i<nums.length;i++){
			int num=nums[i];
			int frequency=num_frequency.getOrDefault(num, 0);		
			frequency++;
			num_frequency.put(num,frequency);
			maxFrequency=maxFrequency>frequency?maxFrequency:frequency;
		}
		String[] bucket=new String[maxFrequency+1];
		Iterator iter = num_frequency.entrySet().iterator();
		while (iter.hasNext()) {
			Map.Entry entry = (Map.Entry) iter.next();
			int num = (int)entry.getKey();
			int frequency = (int)entry.getValue();
			if(bucket[frequency]==null){
				bucket[frequency]=num+"";
			}
			else{
				bucket[frequency]=bucket[frequency]+","+num;
			}			
		}
		int theFrequency=maxFrequency;
		while(k>0){
			String theString=bucket[theFrequency];
			if(theString!=null){
				String[] splitWords=theString.split(",");
				for(int i=0;i<splitWords.length&&k>0;i++){
					result.add(Integer.parseInt(splitWords[i]));
					k--;
				}
			}			
			theFrequency--;
		}
		return result;
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Top_K_Frequent_Elements_347 t=new Top_K_Frequent_Elements_347();
		int k=2;
		int[] nums=new int[]{1,2};
		List<Integer> list=t.topKFrequent(nums, k);
		for(Integer i:list){
			System.out.println(i);
		}
	}

}
有大神的解法跟我一毛一样,只不过bucket数组的类型换了。讲道理我当初也想以list为数组的,但是不会写语法,这个大神给了我样例。

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 && res.size() < k; pos--) {
		if (bucket[pos] != null) {
			res.addAll(bucket[pos]);
		}
	}
	return res;
}
除了桶排序,还可以使用最大堆PriorityQueue和红黑树TreeMap,其中TreeMap的性能是最好的。
优先级队列:

public class Solution {  
    public List<Integer> topKFrequent(int[] nums, int k) {  
        HashMap<Integer, Integer> mp = new HashMap<>();  
        for (int val: nums) {  
            mp.put(val, mp.getOrDefault(val, 0) + 1);  
        }  
        PriorityQueue<Map.Entry<Integer, Integer>> q = new PriorityQueue<>((a, b) -> (b.getValue() - a.getValue()));//最大堆  
        for (Map.Entry<Integer, Integer> entry : mp.entrySet()) {  
            q.add(entry);  
        }  
        List<Integer> ans = new ArrayList<>();  
        while (ans.size() < k) {  
            Map.Entry<Integer, Integer> entry = q.poll();  
            ans.add(entry.getKey());  
        }  
        return ans;  
    }  
}  
TreeMap:

public class Solution {  
    public List<Integer> topKFrequent(int[] nums, int k) {  
        HashMap<Integer, Integer> mp = new HashMap<>();  
        for (int val: nums) {  
            mp.put(val, mp.getOrDefault(val, 0) + 1);  
        }  
        TreeMap<Integer, List<Integer>> freqMap = new TreeMap<>();  
        for (int val: mp.keySet()) {  
            int cur = mp.get(val);  
            if (!freqMap.containsKey(cur)) {  
                freqMap.put(cur, new ArrayList<>());  
            }  
            freqMap.get(cur).add(val);  
        }  
        List<Integer> ans = new ArrayList<>();  
        while (ans.size() < k) {  
            //The pollLastEntry() method is used to remove and returns a key-value mapping 
            //associated with the greatest key in this map, or null if the map is empty.
            Map.Entry<Integer, List<Integer>> entry = freqMap.pollLastEntry(); 
            ans.addAll(entry.getValue());  
        }  
        return ans;  
    }  
} 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值