返回

克服leetcode的 215:找出数组中的第K个最大元素,掌握快排技巧!

前端

导语

算法的世界广阔无垠,LeetCode 作为一道道试炼之门,引领着我们不断攀登。今天,我们聚焦于 215 题:找出数组中的第 K 个最大元素,这是一道考验排序和算法思维的经典难题。本文将深入剖析快排算法,带领你轻松攻克难关,在算法进阶之路上更进一步。

快排算法:高效的排序利器

快排算法是一种高效的排序算法,其核心思想是分治。具体步骤如下:

  1. 选取基准值: 从数组中任意选择一个元素作为基准值。
  2. 划分数组: 将数组分为两部分:小于基准值的元素和大于基准值的元素。
  3. 递归排序: 对两部分分别进行快排,直到所有元素有序。

应用快排解决 LeetCode 215

LeetCode 215 题要求我们找出数组中的第 K 个最大元素。我们可以巧妙地利用快排的思想来解决这个问题:

  1. 初始化: 以数组的最后一个元素为基准值。
  2. 分区: 将数组分为两部分:左部分包含小于基准值的元素,右部分包含大于基准值的元素。
  3. 判断分区: 如果左部分的长度等于 K-1,则基准值就是第 K 大元素。
  4. 递归调用: 如果左部分的长度小于 K-1,则对左部分进行快排;如果左部分的长度大于 K-1,则对右部分进行快排。

通过这种方法,我们可以高效地找到数组中的第 K 个最大元素。

代码实现

public int findKthLargest(int[] nums, int k) {
    return quickSelect(nums, 0, nums.length - 1, k);
}

private int quickSelect(int[] nums, int start, int end, int k) {
    int pivot = nums[end];
    int left = start;
    int right = end - 1;

    while (left <= right) {
        if (nums[left] > pivot) {
            swap(nums, left, right);
            right--;
        } else {
            left++;
        }
    }

    // 此时 left 指向大于基准值的分区边界
    if (left == k - 1) {
        return nums[left];
    } else if (left < k - 1) {
        return quickSelect(nums, left + 1, end, k);
    } else {
        return quickSelect(nums, start, left - 1, k);
    }
}

private void swap(int[] nums, int i, int j) {
    int temp = nums[i];
    nums[i] = nums[j];
    nums[j] = temp;
}

示例

给定数组 nums = [3, 2, 1, 5, 6, 4],找出第 2 大元素。

  1. 以基准值 6 为中心,将数组分为 [3, 2, 1][5, 4]
  2. 左部分长度小于 2-1,因此继续对左部分进行快排。
  3. 以基准值 3 为中心,将左部分分为 [2, 1][3].
  4. 左部分长度等于 2-1,因此基准值 3 就是第 2 大元素。

结语

通过深入理解快排算法,我们巧妙地解决了 LeetCode 215 难题。快排算法在各种排序场景中都有着广泛的应用,掌握其原理和使用技巧,将为你在算法进阶之路上助力良多。算法世界浩瀚无垠,让我们继续探索,不断突破!