力扣题目
解题思路
java代码
力扣题目:
给定整数数组 nums
和整数 k
,请返回数组中第 k
个最大的元素。
请注意,你需要找的是数组排序后的第 k
个最大的元素,而不是第 k
个不同的元素。
你必须设计并实现时间复杂度为 O(n)
的算法解决此问题。
示例 1:
输入: [3,2,1,5,6,4],
k = 2
输出: 5
示例 2:
输入: [3,2,3,1,2,4,5,5,6],
k = 4
输出: 4
提示:
1 <= k <= nums.length <= 105
-104 <= nums[i] <= 104
解题思路:
代码中使用了快速选择算法(Quickselect),这是一种基于快速排序的选择算法。快速选择算法的平均时间复杂度是 O(n),但最坏情况下的时间复杂度是 O(n^2)。与快速排序不同,快速选择算法不需要对整个数组进行分区,它只选择一个基准点(pivot),并根据这个基准点将数组分为两部分,然后递归地在其中一部分中查找所需的元素。
quickselect
函数的工作原理如下:
- 选择数组的第一个元素作为基准点
x
。 - 初始化两个指针
i
和j
,分别指向数组的开始和结束位置。 - 将所有小于
x
的元素移动到i
的右侧,将所有大于x
的元素移动到j
的左侧。 - 检查
k
是否小于或等于j
,如果是,则在i
到j
的范围内递归搜索。 - 否则,在
j+1
到n-1
的范围内递归搜索。 - 重复以上步骤直到找到第
k
大的元素。
findKthLargest2
函数是解决“第 K 大元素”问题的主函数。它接收一个整数数组 _nums
和一个整数 k
,然后调用 quickselect
函数来找到并返回第 k
大的元素。
java代码:
package org.example;
public class Leetcode215 {
public static void main(String[] args) {
int[] nums = {3,2,1,5,6,4};
Leetcode215 leetcode215 = new Leetcode215();
System.out.println(leetcode215.findKthLargest2(nums, 2));
}
int quickselect(int[] nums, int l, int r, int k) {
if (l == r) return nums[k];
int x = nums[l], i = l - 1, j = r + 1;
while (i < j) {
do i++; while (nums[i] < x);
do j--; while (nums[j] > x);
if (i < j){
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
}
if (k <= j) return quickselect(nums, l, j, k);
else return quickselect(nums, j + 1, r, k);
}
public int findKthLargest2(int[] _nums, int k) {
int n = _nums.length;
return quickselect(_nums, 0, n - 1, n - k);
}
// 作者:力扣官方题解
// 链接:https://leetcode.cn/problems/kth-largest-element-in-an-array/solutions/307351/shu-zu-zhong-de-di-kge-zui-da-yuan-su-by-leetcode-/
// 来源:力扣(LeetCode)
// 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
}