求出数组中第K大的数

我们可以用暴力循环来求解,但是如果想把时间复杂度降到O(n),我们可以借用「快速排序」的思想,一次常规操作后,我们的基准值(pivot)会将数组分为两半,前一半是比pivot小的,后一半是比pivot大的。此时这个pivot所处的数组下标为index,那么这个pivot就是整个数组中「第index+1」小的值。同理,如果我们将比pivot大的放在pivot的前半段,把比pivot小的放在pivot的后半段,那么这个pivot其实就是第「index+1」大的值了。如果这个「index+1」刚好等于k,那么我们就可以直接返回这个pivot值,如果「index+1」大于k,说明我们要找的值在arr[0]到arr[index-1]这个前半段区间上,反之则在arr[index+1]-arr[arr.length - 1]这个后半段区间上,然后循环查找。

代码:

function findKMax(arr, k) {
    let len = arr.length;
    let index = quick(0, arr.length - 1, arr);
    while(index + 1 != k) {
        if(index + 1 > k) {
            index = quick(0, index - 1);
        } else {
            index = quick(index + 1, len -1)
        }
    }
    return arr[index];

}

// 一次常规操作,使得pivot前半段比它大,后半段比它小
function quick(start, end, arr) {
    if(start >= end) return;
    let left = start;
    let right = end - 1;
    let key = arr[end];
    while(left < right) {
        while(left < right && arr[left] > key) left++;
        while(left < right && arr[right] < key) right--;
        [arr[left], arr[right]] = [arr[right], arr[left]];
    }
    if(arr[left] <= key) {
        [arr[left], arr[end]] = [arr[end], arr[left]];
    } else {
        left++;
    }
    return left;
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 本文是lhyt本人原创,希望用通俗易懂的方法来理解一些细节和难点。转载时请注明出处。文章最早出现于本人github...
    lhyt阅读 282评论 0 0
  • 第四天 数组【悟空教程】 第04天 Java基础 第1章数组 1.1数组概念 软件的基本功能是处理数据,而在处理数...
    Java帮帮阅读 1,638评论 0 9
  • 某次二面时,面试官问起Js排序问题,吾绞尽脑汁回答了几种,深感算法有很大的问题,所以总计一下! 排序算法说明 (1...
    流浪的先知阅读 1,230评论 0 4
  • 排序算法说明 (1)排序的定义:对一序列对象根据某个关键字进行排序; 输入:n个数:a1,a2,a3,…,an 输...
    code武阅读 694评论 0 0
  • 秋天,烈日当空,道路两旁,成熟的谷物热得弯下腰,低着头。我喜欢烈日,更喜欢秋收季节的烈日。不管烈日怎样烤着我们,我...
    独立安阅读 334评论 0 6