美文网首页
LintCode 544. 前K大数

LintCode 544. 前K大数

作者: Jay_8d33 | 来源:发表于2018-02-03 00:47 被阅读0次

原题

用PriorityQueue的话,极度简单,以前的几道题已经做过无数遍了,直接上答案。

public class Solution {
    /*
     * @param nums: an integer array
     * @param k: An integer
     * @return: the top k largest numbers in array
     */
    public int[] topk(int[] nums, int k) {
        int[] result = new int[k];
        if (nums == null || nums.length < k) {
            return result;
        }
        
        Queue<Integer> pq = new PriorityQueue<>();
        for (int num : nums) {
            pq.add(num);
            if (pq.size() > k) {
                pq.poll();
            }
        }
        
        for (int i = k - 1; i >= 0; i--) {
           result[i] = pq.poll(); 
        }
        
        return result;
    }
}

解2

用QuickSelect做。比普通QuickSelect要多一个步骤,因为这道题不是要第K大的数了,而是要前K个最大的数,同时还要排序。如果不排序,QuickSelect已经做到了,因为在找到第K大的数的时候,已经保证了比它大的都在一边了,那么那一边加上它本身,就是前K个了。题目要求是排序的,所以要再对这一部分进行一下排序。

public class Solution {
    /*
     * @param nums: an integer array
     * @param k: An integer
     * @return: the top k largest numbers in array
     */
    public int[] topk(int[] nums, int k) {
        int[] result = new int[k];
        if (nums == null || nums.length < k) {
            return result;
        }
        
        quickSort(nums, 0, nums.length - 1, k);
        // first k elements are the k largest elements
        quickSort(nums, 0, k - 1, -1);
        for (int i = 0; i < k; i++) {
            result[i] = nums[i];
        }
        
        return result;
    }
    
    private void quickSort(int[] nums, int start, int end, int k) {
        if (start >= end) {
            return;
        }
        
        int left = start;
        int right = end;
        int pivot = nums[start + (end - start) / 2];
        while (left <= right) {
            while (left <= right && nums[left] > pivot) {
                left++;
            }
            
            while (left <= right && nums[right] < pivot) {
                right--;
            }
            
            if (left <= right) {
                int temp = nums[left];
                nums[left] = nums[right];
                nums[right] = temp;
                
                left++;
                right--;
            }
        }
        
        if (k != -1) {
            if (start + k - 1 < right + 1) {
                quickSort(nums, start, right, k);
            } else if (start + k - 1 > right + 1) {
                quickSort(nums, left, end, k - (left - start));
            }
        } else {
            quickSort(nums, start, right, k);
            quickSort(nums, left, end, k);
        }
    }
}

这里我为了省事,直接用QuickSort再sort了一遍,因为QuickSelect跟QuickSort的第一步都是一样的,我用了一个-1当作k的特殊值,如果是-1就用QuickSort,不是就QuickSelect。

分析

第一个方法,时间是O(nlogk),空间是O(k)。第二个方法,基于QuickSelect,空间常数O(1),时间第一步是O(n),再QuickSort前k个数字,即O(klogk),所以总共就是O(n+klogk)。这也很合理,如果k等于n,那么就等于sort了一遍array。

相关文章

  • LintCode 544. 前K大数

    原题 解 用PriorityQueue的话,极度简单,以前的几道题已经做过无数遍了,直接上答案。 解2 用Quic...

  • 544. 前K大数

    在一个数组中找到前K大的数样例给出 [3,10,1000,-99,4,100], k = 3.返回 [1000, ...

  • lintcode 5 寻找第k大数

    5. 在数组中找到第k大的元素 在数组中找到第k大的元素 参考 先排序,再查找。最简单,但是最麻烦,如果不止一次的...

  • Remove K Digits

    https://www.lintcode.com/problem/remove-k-digits/description

  • LintCode 5. Kth Largest Element

    原题 LintCode 5. Kth Largest Element Description Find K-th ...

  • 第k大元素

    (lintcode上面的题解)第k大元素:(从小到大的排序)

  • 面试--算法--Top K

    原文:面试--算法--Top K 总结: 1、找出一个无序数组里面前K个最大数 插入排序 只找前K个数 或者...

  • Top K 问题

    问题描述 有N(N>>10000)个整数,求出其中的前K个最大的数。 问题分析 需要前K个最大数,一定会有比较的过...

  • lintCode题解(3)

    标签(空格分隔): lintCode 题目: 统计数字 描述: 计算数字k在0到n中的出现的次数,k可能是0~9的...

  • lintcode k数和

    给定n个不同的正整数,整数k(k < = n)以及一个目标数字。在这n个数里面找出K个数,使得这K个数的和等于目标...

网友评论

      本文标题:LintCode 544. 前K大数

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