Top-K问题

目录

问题介绍:

利用Java自带的PriorityQueue类解决求数组中TopK的问题

代码

解决leetcode问题:查找最小的k对数字

题目介绍:

题目分析

代码


问题介绍:

创建一个优先级队列(堆)(实际上为一棵二叉树,每个结点始终比左右结点大或者小的二叉树)。例如,求一个数组array当中的最小的k个元素,可以遍历数组,用前k个元素组成一个大堆(此时堆顶元素为最大元素);继续遍历数组中array.length - k个元素,当遍历到的元素小于堆顶元素,将堆顶元素出堆,此元素如堆,再重新调整为大堆,继续遍历直至数组遍历完。此时堆中的k个元素为最小的k个元素。

注意:如果需要求最大的k个元素,则情况相反。

利用Java自带的PriorityQueue类解决求数组中TopK的问题

代码

public static int[] TopK(int[] array,int k) {
        //1.创建一个大小为k的大根堆
        PriorityQueue maxheap = new PriorityQueue<>(k, new Comparator() {
            //内部类当中重写compare函数
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2 - o1;
            }
        });
        //2.遍历数组当中的元素,前k个元素放到队列当中
        for (int i = 0;i < array.length;i++) {
            if (maxheap.size() < k) {
                maxheap.offer(array[i]);
            } else {
                 //3.从第k+1个元素开始,每个元素都与堆顶元素进行比较
                int top = maxheap.peek();
                if (top > array[i]) {
                    maxheap.poll();
                    maxheap.offer(array[i]);
                }
            }
        }
        //安装返回类型,返回整型数组
        int[] tmp = new int[k];
        for (int i = 0; i < k; i++) {
            tmp[i] = maxheap.poll();
        }
        return tmp;
    }

解决leetcode问题:查找最小的k对数字

题目介绍:

Top-K问题_第1张图片

 

题目分析

1.通过示例3可以知道:当要求数对数大于全部数对数时,需注意所能提供的最多数对。

2.两个数组均为升序数组且题目要求最小的k个数对,所以不必提供数对的全部组合可能。

3.做法:创建一个类,在类中创建值分别等于nums1和nums2的元素的值的两个变量,将类加入优先级队列后开始比较。

代码

   class Pair implements Comparable {
        int val1;
        int val2;
        public Pair(int val1, int val2) {
            this.val1 = val1;
            this.val2 = val2;
        }
        @Override
        public int compareTo(Pair o) {
            return (o.val1 + o.val2) - (this.val1 + this.val2);
        }
    }
    public List> kSmallestPairs(int[] nums1, int[] nums2, int k) {
        List> ret = new ArrayList<>();
        //创建一个存放Pair类型的优先级队列
        PriorityQueue queue = new PriorityQueue<>();
        for (int i = 0; i < Math.min(k,nums1.length); i++) {
            for (int j = 0; j < Math.min(k,nums2.length); j++) {
                //如果优先级队列元素不满k个,需要将nums1和nums2的元素匹配放入优先级队列
                if (queue.size() < k) {
                    queue.offer(new Pair(nums1[i],nums2[j]));
                }else {
                    Pair pair = queue.peek();
                    if (nums1[i] + nums2[j] < (pair.val1 + pair.val2)) {
                        queue.poll();
                        queue.offer(new Pair(nums1[i],nums2[j]));
                    }
                }
            }
        }
        // 注意加队列空的判断,k有可能大于最后结果集数量的
        for (int i = 0; i < k && !(queue.isEmpty()); i++) {
            List temp = new ArrayList<>();
            Pair pair = queue.poll();
            temp.add(pair.val1);
            temp.add(pair.val2);
            ret.add(temp);
        }
        return ret;
    }

你可能感兴趣的:(排序算法,算法,数据结构)