美文网首页Java
查找 TopK 问题

查找 TopK 问题

作者: JAVA觅音阁 | 来源:发表于2019-10-26 11:20 被阅读0次

​从海量数字中寻找最大/小的 k 个,这类问题我们称为 TopK 问题。

通常使用数据结构-最大/小堆来解决

  • 求前 k 大,用最小堆,即堆顶元素为堆中最小值。
  • 求前 k 小,用最大堆,即堆顶元素为堆中最大值。

如前k大的值, 传入列表 list=[12, 39, 3, 72, 56, 81, 15, 9, 103] 和 k=3, 输出 [103, 81, 72]。
如前k小的值, 传入列表 list=[12, 39, 3, 72, 56, 81, 15, 9, 103] 和 k=3, 输出 [3, 9, 12]。

前K大值

思路:

迭代列表元素:

  • 1.先放入元素前 k 个建立一个最小堆;
  • 2.当前元素x若大于堆顶元素:移除堆顶元素并入队x;
  • 3.最后获取 最小堆 中的值,即为 topK4Max。

JAVA参考代码

public static int[] topK4Max(int[] nums, int k) {
​
    // 优先队列、从小到大 (默认也是自然排序)
    Queue<Integer> minHeap = new PriorityQueue<>(Comparator.naturalOrder());
    // 建立最小堆
    for (int i = 0, len = nums.length; i < len; i++) {
        if (minHeap.size() < k) {
            minHeap.offer(nums[i]); // 入队
            continue;
        }
        if (nums[i] > minHeap.peek()) { // 取队首元素比较,不移除
            minHeap.poll(); // 取队首元素,并移除
            minHeap.offer(nums[i]);
        }
    }
    // 遍历队列
    List<Integer> list = new ArrayList<>();
    Iterator<Integer> iterator = minHeap.iterator();
    while (iterator.hasNext()){
        list.add(iterator.next());
    }
    // 从大到小排序
    Collections.sort(list, (o1, o2) -> o1 < o2 ? 1 : o1 == o2 ? 0 : -1);
    // 转换成数组
    return list.stream().mapToInt(Integer::valueOf).toArray();
​
}

前K小值

思路:

迭代列表元素:

  • 1.先放入元素前 k 个建立一个最大堆;
  • 2.当前元素x若小于堆顶元素:移除堆顶元素并入队x;
  • 3.最后获取 最大堆 中的值,即为 topK4Min。

JAVA参考代码

public static int[] topK4Min(int[] nums, int k) {
​
    // 优先队列、从大到小排序
    Queue<Integer> maxHeap = new PriorityQueue<>(Comparator.reverseOrder());
    // 建立最大堆
    for (int i = 0, len = nums.length; i < len; i++) {
        if (maxHeap.size() < k) {
            maxHeap.offer(nums[i]); // 入队
            continue;
        }
        if (nums[i] < maxHeap.peek()) { // 取队首元素比较,不移除
            maxHeap.poll(); // 取队首元素,并移除
            maxHeap.offer(nums[i]);
        }
    }
    // 遍历队列
    List<Integer> list = new ArrayList<>();
    Iterator<Integer> iterator = maxHeap.iterator();
    while (iterator.hasNext()){
        list.add(iterator.next());
    }
    // 从小到大排序
    Collections.sort(list);
    // 转换成数组
    return list.stream().mapToInt(Integer::valueOf).toArray();
    
}

测试代码

public static void main(String[] args) {
    int[] nums = new int[]{12, 39, 3, 72, 56, 81, 15, 9, 103};
​
    int[] maxK = topK4Max(nums, 3);
    System.out.println(JSON.toJSONString(maxK));
​
    int[] minK = topK4Min(nums, 3);
    System.out.println(JSON.toJSONString(minK));
}

相关文章

  • 查找 TopK 问题

    ​从海量数字中寻找最大/小的 k 个,这类问题我们称为 TopK 问题。 通常使用数据结构-最大/小堆来解决 求前...

  • 海量数据处理

    topk问题

  • (12)海量数据处理

    海量数据处理主要涉及分治算法,其中包含排序、求TopK、以及查找重复的问题 (1)Top K 算法思路:(1) 局...

  • TopK 问题

    TopK分为两种:离线处理和实时流处理 非频率的 TopK 问题直接采用 PriorityQueue 就可以解决 ...

  • TopK问题

    出现次数最多的K个 解题步骤: 把所有的数据存到map里 构造K个的大根堆 输出大根堆 第K大的数 解题步骤: 方...

  • TopK问题

    从文件中输出请求最频繁的10个 HTTP 接口,及其相应的请求数量数据格式如下 从大数据中找到TopK个数,比较经...

  • topK问题

    连接:https://leetcode-cn.com/problems/top-k-frequent-elemen...

  • topk 问题

    排序后取前 K 个 算法复杂度 O(nlogn) 遍历 K 遍 算法复杂度 O(kn) k 跟元素的小/大根堆 算...

  • topK问题

    (1)时间复杂度分析:每次调用'self.heapAdjust(self.arr, n, i)'的时间复杂度是O(...

  • TOPK 问题

    TOPK 问题 描述 如从海量数字中寻找最大的 k 个,这类问题我们称为 TOPK 问题,通常使用堆来解决: 求前...

网友评论

    本文标题:查找 TopK 问题

    本文链接:https://www.haomeiwen.com/subject/oupyvctx.html