美文网首页
一道算法题:第K大的数

一道算法题:第K大的数

作者: 不可思议的Mark | 来源:发表于2017-03-31 15:48 被阅读565次

    给一个无序的包涵n个元素的数组,找出其中第k大的数(n > k)。
    初看到这个题的时候,作为一个写了一段时间java的人,立刻能想到的一种解法就是:

    class Solution {
        public int kthLargestElement(int k, int[] nums) {
            Arrays.sort(nums);
            return nums[nums.length - k];
        }
    };
    

    时间复杂度时NlgN, 空间复杂度时O(1).
    看起来貌似不错,但既然这道题目被广泛地讨论,就肯定还有其他解法,比如说:

    class Solution {
        public int kthLargestElement(int k, int[] nums) {
            // write your code here
            PriorityQueue<Integer> pq = new PriorityQueue<>();
            for(int val : nums) {
                pq.add(val);
                if(pq.size() > k) {
                    pq.poll();
                }
            }
            return pq.peek();
        }
    };
    

    当然建堆需要额外的空间,而且时间复杂度上并没有多少提升,所以不能算什么优化。
    更好的一种解法是利用快速排序的划分思想,这种解法是一种O(n)的解法

    class Solution {
        
        public int kthLargestElement(int k, int[] nums) {
            //打乱数组避免最坏情况
            shuffle(nums);
            k = nums.length - k;
            int lo = 0, hi = nums.length - 1;
            while(lo < hi){
                int j = partition(nums, lo, hi);
                if(j < k){
                    lo = j + 1;
                }else if(j > k){
                    hi = j - 1;
                }else{
                    break;
                }
            }
            return nums[k];
        }
        
        private int partition(int[] nums, int lo, int hi){
            int i = lo;
            int j = hi + 1;
            while(true){
                while(i < hi && nums[++i] < nums[lo]);
                while(j > lo && nums[lo] < nums[--j]);
                if(j <= i) break;
                exch(nums, i, j);
            }
            exch(nums, lo, j);
            return j;
        }
        
        private void exch(int[] nums, int i, int j){
            int temp = nums[i];
            nums[i] = nums[j];
            nums[j] = temp;
        }
      
        private void shuffle(int a[]) {
            Random random = new Random();
            for(int ind = 1; ind < a.length; ind++) {
                int r = random.nextInt(ind + 1);
                exch(a, ind, r);
            }
        }
    };
    

    相关文章

      网友评论

          本文标题:一道算法题:第K大的数

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