215. 数组中的第K个最大元素
难度:中等
在未排序的数组中找到第 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 ≤ 数组的长度。
力扣:
https://leetcode-cn.com/problems/kth-largest-element-in-an-array/
解题思路:
基于快排思路,降序排列,取前K个数字。
代码:
package com.ziling.goodlife.study;
import java.util.Arrays;
/**
* @Author: yipeng
* @Date: 2021/6/21 00:06
*/
public class TopKmax {
/**
* 最小的K个数,快排解法,修改原数组, 时间复杂度O(N)
* @param nums
* @param k
*/
public static int[] topKmax(int[] nums, int k) {
if (nums == null || k <= 0 || nums.length < k) {
throw new RuntimeException("invalid param");
}
int left = 0;
int right = nums.length - 1;
int index = partition(nums, left, right);
while (index != k - 1) {
if (index < k - 1) {
index = partition(nums, index + 1, right);
} else {
index = partition(nums, left, index - 1);
}
}
return Arrays.copyOf(nums, k);
}
private static int partition(int[] nums, int left, int right) {
int x = nums[left];
while (left < right) {
// 由于上方判断条件为“index != k - 1”,此处必须加等号,否则会出现跳过相等情况,进而造成死循环。
while (left < right && nums[right] <= x) {
right--;
}
if (left < right) {
nums[left++] = nums[right];
}
while (left < right && nums[left] > x) {
left++;
}
if (left < right) {
nums[right--] = nums[left];
}
nums[left] = x;
}
return left;
}
public static void print(int[] nums) {
for (int num : nums) {
System.out.print(num + " ");
}
System.out.println();
}
public static void main(String[] args) {
int[] nums = {34,23,6435,4234,2523,425235,234234,6345,23,54,43,23,23,43,53,2,423,6345,432,24,25,2,234,53,6546,5345,2342,63534,234,4364};
print(nums);
print(topKmax(nums, 10));
// 此情况下可构建出死循环
// topKmax.print(topKmax.topKmax(nums, 20));
}
}
注意:
区别于快排,在topK问题中,
由于分段的判断条件为while (index != k - 1),
下方判断条件while (left < right && nums[right] <= x)中,必须加等号。
否则,数组存在重复数据的情况下,会出现跳过重复数据下标的情况,进而造成程序死循环。
举例:上例中,如果下方循环判断条件未加等号,topKmax.topKmax(nums, 20)会出现死循环。
结论:
时间复杂度:O(N)
最优时间复杂度:O( k*log2n )
空间复杂度为:O( 1 )
计算依据:近似 O(N)+O(N/2)+O(N/4)+……<O(2N)
弊端:
1. 需要提前将全部数据读入,海量数据来说,对空间开销很大
2. 改变数组原有顺序
参考堆排序:https://blog.youkuaiyun.com/longziling/article/details/118095153

本文介绍了一种基于快速选择算法在未排序数组中找到第K个最大元素的方法。通过调整快排的分治策略,寻找第K个最大元素而非完全排序。在最坏情况下,算法的时间复杂度为O(N),平均时间复杂度为O(N)。文章还特别指出,当数组中有重复元素时,判断条件的正确设置对于避免死循环至关重要。同时,该方法会改变原数组顺序并需要预先加载所有数据,对于大数据处理可能不适用。
473

被折叠的 条评论
为什么被折叠?



