【算法-LeetCode】215. 数组中的第K个最大元素(暴力sort;快速排序)

LeetCode215. 数组中的第K个最大元素

发布:2021年7月29日17:34:28

问题描述及示例

给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。
请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

示例 1:
输入: [3,2,1,5,6,4] 和 k = 2
输出: 5
示例 2:
输入: [3,2,3,1,2,4,5,5,6] 和 k = 4
输出: 4
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/kth-largest-element-in-an-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

提示:
1 <= k <= nums.length <= 104
-104 <= nums[i] <= 104

我的题解

我的题解1(简单粗暴,调用sort)

其实一开始看到这题,我心里第一反应就是调用JavaScript数组的sort()方法然后直接返回排序后的nums数组中的某个数,当然其下标应该是和k有关的。此时我心里就犯了嘀咕:就这?不会吧?算了我先按照最开始的想法写出来吧。思路也是简单粗暴非常直接。首先是把传入的nums数组调用原生的数组方法sort()进行排序。然后返回排序后的数组中符合题意的那一项。其中我向sort()函数中传入的相关回调函数是经典的降序函数,这样一来返回值的下标也就确定了:k-1。OK,完活儿收工~

/**
 * @param {number[]} nums
 * @param {number} k
 * @return {number}
 */
// 思路很简单,就不多写注释了吧
var findKthLargest = function(nums, k) {
  nums.sort((a, b) => b - a);
  return nums[k-1];
};


提交记录
32 / 32 个通过测试用例
状态:通过
执行用时:72 ms, 在所有 JavaScript 提交中击败了95.84%的用户
内存消耗:39.3 MB, 在所有 JavaScript 提交中击败了60.08%的用户
时间:202172917:41:03

我以为就算LeetCode上执行代码中的测试用例能过,提交之后也无法通过全部后台用例。结果,从开始写到点击提交,甚至不到一分钟,这道题就提交通过了!而且执行效率好像也没有我想像中的那样不堪入目。em……这还是道难度中等的题,直觉告诉我:肯定有妖。但我怎么想不到啥更简单直接的方法了呀,那估计是要从效率方面考虑了吧,我猜想sort()函数的排序效率可能不是那么高,应该要从这一点入手吧。(说明一下,我可不是抖M啊,我只是对真理有强烈的探索欲~)

我的题解2(快速排序)

更新:2022/02/07 19:56

这道题的核心考察点还是排序。上面是对所有的元素都进行了排序操作,如果利用快速排序的【一趟排序即可确定某个元素的最终位置】的特点,我们就可以不必让所有元素都参与排序,只要得到了那个预期位置(即倒数第 k 个元素)的元素值就可以终止程序。

/**
 * @param {number[]} nums
 * @param {number} k
 * @return {number}
 */
var findKthLargest = function(nums, k) {
  // partition 是一趟排序的操作,其返回枢纽元素 pivot 在 nums 数组中的最终位置
  function partition(arr, low, high) {
    let pivot = arr[high];
    let p = low;
    for(let i = low; i < high; i++) {
      if(arr[i] < pivot) {
        [arr[i], arr[p]] = [arr[p], arr[i]];
        p++;
      }
    }
    [arr[p], arr[high]] = [arr[high], arr[p]];
    return p;
  }

  let low = 0;
  let high = nums.length - 1;

  while(true) {
    let pivotPosition = partition(nums, low, high);
    // 如果发现本次快排后,枢纽元素刚好处在倒数第k个位置,那就可以直接将该枢纽元素返回了
    // 剩余元素不必再参与排序过程
    if(pivotPosition === nums.length - k) {
      return nums[pivotPosition];
    } else if (pivotPosition < nums.length - k) {
      low = pivotPosition + 1;
    } else {
      high = pivotPosition - 1;
    }
  }
};


提交记录
32 / 32 个通过测试用例
状态:通过
执行用时:96 ms, 在所有 JavaScript 提交中击败了30.22%的用户
内存消耗:42.8 MB, 在所有 JavaScript 提交中击败了12.01%的用户
时间:2022/02/07 19:56

【更新结束】

官方题解

更新:2021年7月29日18:43:21

因为我考虑到著作权归属问题,所以【官方题解】部分我不再粘贴具体的代码了,可到下方的链接中查看。

更新:2021年7月29日18:32:38

参考:数组中的第K个最大元素 - 数组中的第K个最大元素 - 力扣(LeetCode)

【更新结束】

其实此前我就有过纠结:写LeetCode题解的博客到底该算转载还是该算原创呢?我看到其他人写的题解博客基本上都是声明的原创,于是就决定也声明为原创,但是今天又仔细想了想,如果在官方题解这种代码也大量复制的前提下,声明原创还是不妥,但我也不愿意轻易地就改为转载,于是我决定把官方题解的方式以链接的方式给出(虽然这样查看的时候确实有点不大方便了)。当然,其实粘贴过来的原题也应该这样,但是那也未免也太不方便了,所以目前先这样吧,等有其他问题了再说。我先去把此前写的LeetCode题解博客中的【官方题解】部分改为相应的链接吧。

【更新结束】

有关参考

更新:2021年7月29日18:28:03
参考:Array.prototype.sort() - JavaScript | MDN
参考:JavaScript的sort()函数,排序return原理是什么? - 知乎
参考:JS中sort()方法原理及使用 - 赛飞 - 博客园

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值