Javascript 数组中第k个最大元素

Javascript 数组中第k个最大元素,javascript,algorithm,Javascript,Algorithm,正在处理此leetcode: 这是我的js代码: var findKthLargest = function(n, k) { // largest at 1st global.arr = new Array(k).fill(false); // loop n for(let i=0; i<n.length; i++) { // allocate this # allocate(n[i]); } co

正在处理此leetcode:

这是我的js代码:

var findKthLargest = function(n, k) {
    // largest at 1st
    global.arr = new Array(k).fill(false);

    // loop n
    for(let i=0; i<n.length; i++) {
        // allocate this #
        allocate(n[i]);    
    }

    console.log('end', arr);

    return arr[0];
};

// n single #
var allocate = function(n) {
    // start from largest
    for(let i=arr.length-1; i>=0; i--) {
        // not set OR > curr, < prev
        if(arr[i] === false || n > arr[i]) {

            console.log('before s', arr);

            shift(i, n);
            return; // need to get out now, otherwise keep overwriting

            console.log('after s', arr);
        }    
    }    
}

// n single #
var shift = function(ind, n) {
    // n > arr[ind]
    // e.g. 6 in, [3, 4, 5, 7], ind == 2, 
    // 7 intact, 4 overwrite 3, 5 overwrite 4, 6 overwrite 5
    let i;
    for(i=1; i<=ind; i++) {
        arr[i-1] = arr[i];    
    }

    // shift done, now inject
    arr[i-1] = n;
}
有人有提示吗?

您可以使用以下算法高效地找到第k个最大值:

/**
 * @param {number[]} nums
 * @param {number} k
 * @return {number}
 */
var findKthLargest = function(nums, k) {
    return nums.sort(function(a,b) { return b-a })[k-1];
};
  • 构建前k个元素的最小堆。时间复杂度=O(k)
  • 对于所有剩余值:当该值大于堆的根时,将根设置为该值并恢复堆。时间复杂度=O((n-k)*logk)
  • 堆的根现在具有第k个最大值。时间复杂度=O(1)
  • 总时间复杂度=O(k+(n-k)*logk)

    函数heapify(arr,i=0,value=arr[i]){ while(true){ 设j=i*2+1; 如果(j+1arr[j+1])j++;//选择值最小的子项 如果(j>=arr.length | value>1;i>=0;i--)heapify(arr,i); 返回arr; } 函数findKthLargest(nums,k){ const heap=buildHeap(nums.slice(0,k)); for(设i=k;iheap[0])heapify(heap,0,nums[i]); } 返回堆[0]; } const nums=[…数组(5000).keys()];//问题中的数组 console.log(findKthLargest(nums,5000));/0使用以下算法可以高效地找到第k个最大值:

  • 构建前k个元素的最小堆。时间复杂度=O(k)
  • 对于所有剩余值:当该值大于堆的根时,将根设置为该值并还原堆。时间复杂度=O((n-k)*logk)
  • 堆的根现在具有第k个最大值。时间复杂度=O(1)
  • 总时间复杂度=O(k+(n-k)*logk)

    函数heapify(arr,i=0,value=arr[i]){ while(true){ 设j=i*2+1; 如果(j+1arr[j+1])j++;//选择值最小的子项 如果(j>=arr.length | value>1;i>=0;i--)heapify(arr,i); 返回arr; } 函数findKthLargest(nums,k){ const heap=buildHeap(nums.slice(0,k)); for(设i=k;iheap[0])heapify(heap,0,nums[i]); } 返回堆[0]; } const nums=[…数组(5000).keys()];//问题中的数组
    控制台日志(findKthLargest(nums,5000))/0测试用例在登录墙后面。你不能在原始问题中添加测试用例吗?不确定你的算法做了什么,但它似乎不能快速选择哪个应该是这个问题的最佳算法。
    5000
    是该测试用例的
    k
    吗?这是否意味着返回
    kthLargest
    是zweo(
    0
    )?我想我发现了这个问题。请注意,func-findKthLargest中有一个名为n的变量,而func-shift和func-allocate中有一个名为n的变量。我将func-findKthLargest中的n改为nums。它通过了。@不仅仅是yeti,是的,你是对的。测试用例在登录墙后面。你不能在原始问题中添加测试用例吗?不确定你的算法是什么,但是它似乎没有快速选择哪个应该是这个问题的最佳算法。对于那个测试用例,
    5000
    k
    吗?这是否意味着返回的
    kthLargest
    是zweo(
    0
    )?我想我发现了这个问题。请注意,func findKthLargest中有一个名为n的变量,而func shift和func allocate中有一个名为n的变量。我将func findKthLargest中的n更改为nums。它通过了。@不仅仅是雪人,是的,你是正确的。我可以问一下让I=(arr.length-1)做什么吗>>1;意思是我想你会问关于操作符的问题。对于参数1,它就像是除以2,然后把地板换成整数。所以你会得到与
    let i=Math.floor((arr.length-1)/2);
    相同的结果。在这种情况下,它给出了仍然有子节点的最深节点的索引。我可以问一下let i=(arr.length-1)是什么吗>>1;我的意思是,我想你问一下操作符。参数1就像除以2,再加上整数。所以你可以得到与
    让i=Math.floor((arr.length-1)/2);
    相同的结果。在这种情况下,它给出了仍然有子节点的最深节点的索引。这是最快的一个!@Kishan,这的时间复杂度是O(nlogn),虽然它在O(k+(n-k)*logk中是可能的。显然,这意味着对于足够大的n,这个解决方案不是最快的。哦,是的,我可能需要测试更大范围的结果。我做得对。这里我来投票我们的答案:这是最快的一个!@Kishan,这的时间复杂度是O(nlogn),而在O(k+(n-k)中是可能的*显然,这意味着对于足够大的n,这个解决方案不是最快的。哦,是的,我可能需要测试更大范围的结果。我做得对。这里我们来投票赞成:D
    /**
     * @param {number[]} nums
     * @param {number} k
     * @return {number}
     */
    var findKthLargest = function(nums, k) {
        return nums.sort(function(a,b) { return b-a })[k-1];
    };