实现思路:
选择小顶堆:维护当前最高的K个元素,堆顶是这K个中的最小值。新元素若大于堆顶,则替换堆顶并调整堆,确保堆中始终为Top K大元素。
插入逻辑:堆未满时直接插入;堆满时,新元素大于堆顶则替换,否则忽略。
获取排行榜:取出堆元素并按热度降序排列。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
| import java.util.*;
public class HotSearchRanking {
static class HotSearchItem { private final String keyword; private final int heat;
public HotSearchItem(String keyword, int heat) { this.keyword = keyword; this.heat = heat; }
public int getHeat() { return heat; }
public String getKeyword() { return keyword; }
@Override public String toString() { return keyword + "(" + heat + ")"; } }
private final PriorityQueue<HotSearchItem> minHeap; private final int k;
public HotSearchRanking(int k) { this.k = k; this.minHeap = new PriorityQueue<>(Comparator.comparingInt(HotSearchItem::getHeat)); }
public void add(HotSearchItem item) { if (item == null) return; if (minHeap.size() < k) { minHeap.offer(item); } else { if (item.getHeat() > minHeap.peek().getHeat()) { minHeap.poll(); minHeap.offer(item); } } }
public List<HotSearchItem> getTopK() { List<HotSearchItem> result = new ArrayList<>(minHeap); result.sort(Comparator.comparingInt(HotSearchItem::getHeat).reversed()); return result; }
public static void main(String[] args) { HotSearchRanking ranking = new HotSearchRanking(3); ranking.add(new HotSearchItem("Java", 50)); ranking.add(new HotSearchItem("Python", 30)); ranking.add(new HotSearchItem("C++", 70)); ranking.add(new HotSearchItem("JavaScript", 60)); ranking.add(new HotSearchItem("Go", 65));
List<HotSearchItem> top = ranking.getTopK(); System.out.println("实时热搜排行榜TOP3:"); for (HotSearchItem item : top) { System.out.println(item); } } }
|
该方法确保每次插入和调整的时间复杂度为O(log K),获取排行榜的时间复杂度为O(K log K),适合处理实时更新的热搜数据。