N个数中第K大的数


过年了看一下博客,去年产量好低,今年争取一周至少一篇吧,水的也行,嘿嘿(注意这儿只有两个嘿嘿,它是语气词,不是动词)。

我们看一下求N个数(可重复)中第K大的数怎么搞, 首先最常见的思路肯定就是先把N个数进行去重排序,我们可以用一下ES6的Set去重,然后用数组sort排序,最后取第K大的就行

下面的代码用到了一些ES6的特性,建议安装babel(npm install -g babel),然后在命令行下使用babel-node运行

或者可以在我弄的这个网页版的repl里运行代码,在控制台里看结果

function q (arry, k) {
  let uniqArry = [...new Set(arry)]
  return uniqArry.sort((a, b) => a - b)[k - 1]
}

console.log(q([1, 3, 4, 8, 12, 5], 4) === 5)
console.log(q([9, 3, 6, 1, 90], 3) === 6)
console.log(q([1, 3, 4, 8, 12, 5], 4) === 5)
console.log(q([1, 3, 4, 8, 12, 5, 4, 9, 110, 234, 355], 4) === 5)
console.log(q([31, 2, 33, 16,
    37, 8, 3, 4,
    33, 28, 17, 38,
    36, 10, 11, 13,
    4, 0, 39, 9 ], 10) === 16)

同时我在下面写了五个测试用例,运行一下返回两个true就行啦

这篇太水了,下面补上一个稍微复杂一点的解法,第二种方法同样是先利用Set去重,然后先取前k个数排序, 再把后面的m-k个数挨个处理一下,比排序后最大的数还小,那就插入到排序数组里特定的位置, 同时数组pop出一个元素,最后取排序后数组里最后一个元素就是所需要的结果。

function q (arry, k) {
  let uniqArry = [...new Set(arry)]
  let tmp = uniqArry.slice(0, k).sort((a, b) => a - b)
  let cur
  for (let i = k, len = uniqArry.length; i < len; i++) {
    cur = uniqArry[i]
    if (cur < tmp[k - 1]) { // 比最大小
      for (let m = 0; m < k; m++) {
        if (cur < tmp[m]) { // 比当前元素小,插入
          tmp.splice(m, 0, cur)
          tmp.pop()
          break
        }
      }
    }
  }

  return tmp[k - 1]
}

console.log(q([1, 3, 4, 8, 12, 5], 4) === 5)
console.log(q([9, 3, 6, 1, 90], 3) === 6)
console.log(q([1, 3, 4, 8, 12, 5], 4) === 5)
console.log(q([1, 3, 4, 8, 12, 5, 4, 9, 110, 234, 355], 4) === 5)
console.log(q([31, 2, 33, 16,
    37, 8, 3, 4,
    33, 28, 17, 38,
    36, 10, 11, 13,
    4, 0, 39, 9 ], 10) === 16)

第二种方法实质是用了分块处理,在数据量特别大的时候也许有用。


推荐文章