【海量数据问题】Java实现topK问题

题目(19年头条秋招现场手撕代码,没错就是这么恐怖。。。)

假如抖音里面有5亿用户,那么每个用户打开一次抖音就有5亿条记录,如果每个用户打开两次抖音,就有10亿条记录。也就是说,用户每打开一次抖音,就记录一下他的uid。
问题:请找出打开抖音次数最频繁的前10个用户。

总体思路

参考这个博主,思路很清晰的!!!https://www.cnblogs.com/qlky/p/7512199.html

  1. 使用一个hashmap统计出现过的uid及其次数
  2. 使用PriorityQueue实现优先队列,最多的k个出现次数;
  3. 对应到hashmap中找到出现最多的k个uid即可。
    ps:我觉得2,3两步可以合并为一步,但是我实在是不知道怎么实现了= =

我的代码 --version 1.0

package topKQues;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.HashMap;
import java.io.FileReader;
import java.io.IOException;
import java.io.BufferedReader;

public class TopKwithPriorityQueue<E extends Comparable> {
	static String filepath = "/Users/alicelmx/java_workspace/algorithm_java8/src/topKQues/demo.txt";
    PriorityQueue<E> queue ;
    static int K ; 

    public TopKwithPriorityQueue(int maxSize) {
    	if (maxSize <= 0)
    		throw new IllegalArgumentException();
    	this.K = maxSize;
    	this.queue = new PriorityQueue<>(maxSize, new Comparator<E>() {
    		@Override
    		public int compare(E o1, E o2) {
    			// 小根堆使用o1-o2
    			return (o1.compareTo(o2)); 
    		}
    	});
    }

    public void add(E e) {
    	if(queue.size() < K)
    		queue.add(e);
    	else {
    		E peek = queue.peek();       
    		if(e.compareTo(peek) > 0) {
    			queue.poll();
    			queue.add(e);
    		}
    	}
    }

    public ArrayList<E> sortedList() {
    	ArrayList<E> list = new ArrayList<E>(queue);
    	return list;
    }
    
    public static HashMap<String,Integer> readAndConvert() {
    	HashMap<String,Integer> map = new HashMap<String,Integer>();
    	try {
			FileReader fr = new FileReader(filepath);
			BufferedReader bf = new BufferedReader(fr);
			String str;
			// 按行读取字符串
			while ((str = bf.readLine()) != null) {
				if(!map.containsKey(str))
					map.put(str,1);
				else {
					int time = map.get(str);
					map.put(str,time+1);
				}
			}
			bf.close();
			fr.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
    	return map;
    }
    public static void main(String[] args) {
    	HashMap<String,Integer> map = readAndConvert();
    	TopKwithPriorityQueue pq = new TopKwithPriorityQueue(2);
        for(String key: map.keySet())
        	pq.add(map.get(key));
        ArrayList<String> res = new ArrayList<>();
        for(int i=0;i<pq.sortedList().size();i++) {
        	for(String key:map.keySet()) {
        		if(map.get(key).equals(pq.sortedList().get(i))&&!res.contains(key))
        			res.add(key);	
        	}
        }
        System.out.println(res);
    }
}

你可能感兴趣的:(求职,Java和Spark,面试中手撕过的那些题目)