📅  最后修改于: 2023-12-03 14:57:48.512000             🧑  作者: Mango
资质 | 算术能力 4 | 问题 5 是 LeetCode 上的一道经典算法题目。本题要求编写程序,在一个未排序的整数数组中找到第 k 个最大的元素。此题考察了算法的时间复杂度和空间复杂度。
给定整数数组 nums 和整数 k,请编写程序在 nums 中找到第 k 个最大的元素。
说明: 你可以假设 k 总是有效的,且 1 ≤ k ≤ 数组长度。
示例 1:
输入: [3,2,1,5,6,4] 和 k = 2
输出: 5
示例 2:
输入: [3,2,3,1,2,4,5,5,6] 和 k = 4
输出: 4
本题的解法有很多,可用的算法包括快速排序、堆排序、冒泡排序等等。在这里,我们介绍一种时间复杂度为 O(nlogn) 的解法——快速排序。(堆排序的时间复杂度也为 O(nlogn),但堆排序的实现通常更为复杂)
快速排序的算法思想是分治法。它从数组中取出一个数作为基准数(pivot,通常选最后一个元素),将数组中所有小于基准数的数放在其左边,所有大于基准数的数放在其右边,再对左右两个子数组递归调用快速排序函数。
具体实现过程如下:
解法的核心是将数组中小于基准数的元素移到左边,大于等于基准数的元素移到右边。这可以通过双指针的方式实现。具体解法如下:
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
quickSort(nums, 0, nums.size() - 1);
return nums[nums.size() - k];
}
void quickSort(vector<int>& nums, int left, int right) {
if (left >= right) return;
int pivot = nums[right];
int i = left, j = right;
while (i < j) {
while (i < j && nums[i] < pivot) i++;
while (i < j && nums[j] >= pivot) j--;
if (i < j) swap(nums[i], nums[j]);
}
swap(nums[i], nums[right]);
quickSort(nums, left, i - 1);
quickSort(nums, i + 1, right);
}
};
本题考察了算法的时间复杂度和空间复杂度。快速排序的时间复杂度为 O(nlogn),空间复杂度为 O(logn)。本题需要找到第 k 个最大的元素,因此需要将整个数组排序后才能得到该元素,因此时间复杂度最好也为 O(nlogn)。因此本题解法的时间复杂度已经达到了最优解。