返回
克服leetcode的 215:找出数组中的第K个最大元素,掌握快排技巧!
前端
2024-02-12 21:28:32
导语
算法的世界广阔无垠,LeetCode 作为一道道试炼之门,引领着我们不断攀登。今天,我们聚焦于 215 题:找出数组中的第 K 个最大元素,这是一道考验排序和算法思维的经典难题。本文将深入剖析快排算法,带领你轻松攻克难关,在算法进阶之路上更进一步。
快排算法:高效的排序利器
快排算法是一种高效的排序算法,其核心思想是分治。具体步骤如下:
- 选取基准值: 从数组中任意选择一个元素作为基准值。
- 划分数组: 将数组分为两部分:小于基准值的元素和大于基准值的元素。
- 递归排序: 对两部分分别进行快排,直到所有元素有序。
应用快排解决 LeetCode 215
LeetCode 215 题要求我们找出数组中的第 K 个最大元素。我们可以巧妙地利用快排的思想来解决这个问题:
- 初始化: 以数组的最后一个元素为基准值。
- 分区: 将数组分为两部分:左部分包含小于基准值的元素,右部分包含大于基准值的元素。
- 判断分区: 如果左部分的长度等于 K-1,则基准值就是第 K 大元素。
- 递归调用: 如果左部分的长度小于 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 大元素。
- 以基准值 6 为中心,将数组分为
[3, 2, 1]
和[5, 4]
。 - 左部分长度小于 2-1,因此继续对左部分进行快排。
- 以基准值 3 为中心,将左部分分为
[2, 1]
和[3]
. - 左部分长度等于 2-1,因此基准值 3 就是第 2 大元素。
结语
通过深入理解快排算法,我们巧妙地解决了 LeetCode 215 难题。快排算法在各种排序场景中都有着广泛的应用,掌握其原理和使用技巧,将为你在算法进阶之路上助力良多。算法世界浩瀚无垠,让我们继续探索,不断突破!