Leetcode215 数组中第K个最大的元素 | 刷题打卡

324 阅读3分钟

题目描述

在未排序的数组中找到第 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

说明: 你可以假设 k 总是有效的,且 1 ≤ k ≤ 数组的长度。

解题思路

题目给定的数组是无序的,所以要想得到数组中第K个大的值,首先就得先给数组进行排序,排好序之后那么要想取得数组中第K个大的值就很简单了。

思路一 、 数组排序

根据题目可知给定数组是无序的,那么我们要返回第K个大的元素,那么第一想到的就应该是直接调用sort()给数组排序,如果升序,那么排序后的数组中的第K个大的元素即 nums[ nums.length - k ]为所求的值;如果是倒序,那么第 K 个大的元素即nums[ k - 1 ] 为所求的值。

思路二、 原地快排

给定一个中间值,一个左边界left,一个右边界right,将所有比这个中间值小的放在中间值的左边(或右边),比中间值大的放在中间值的右边(或左边),那么这时就可理解为现在有两个区域,左区域和右区域。之后再对这两个区域进行递归,即可实现原地快排。

AC代码

题解一 数组排序

var findKthLargest = function (nums, k) {
    return nums.sort((a,b) => a-b)[nums.length - k]
}

题解二 原地快排

/**
 * @param {number[]} nums
 * @param {number} k
 * @return {number}
 */

function partition(arr, left, right) {
  if (left >= right) return // 终止条件,当数组左边界大于等于右边界时,就结束递归
  let private = arr[left] // 给定中间值
  let i = left, j = right
  while (i < j) {
      while (arr[j] <= private && i < j) { // 如果比中间值小,就放在右边
          j--
      }
      arr[i] = arr[j] // 比中间值大就交换到前面
      while (arr[i] >= private && i < j) { // 如果比中间值大,不动
          i++
      }
      arr[j] = arr[i] // 如果比中间值小,就放在中间值的右边
  }
  arr[i] = private // 这是以 i 为分界,左边都是比中间值大的,右边都是比中间值小的,这是再把中间值重新赋给下标 i 的元素,就实现了一次排序
  partition(arr, left, i - 1) // 对比中间值大的值即左边区域进行排序
  partition(arr, i + 1, right) // 对比中间值小的值即右边区域进行排序
}
function sort(arr) {
  partition(arr, 0, arr.length - 1)
  return arr
}

var findKthLargest = function (nums, k) {
  return sort(nums)[k-1]
};

总结

力扣上给的相关标签是堆和分治算法,不过我只想到排序,算法还有很远的路要走呀,明天也要加油哦。如果有小伙伴觉得还不错,希望可以点个赞哦

本文正在参与「掘金 2021 春招闯关活动」, 点击查看活动详情