Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit eb478a9

Browse files
committed
kth largest element in an array
1 parent 46a5629 commit eb478a9

File tree

3 files changed

+151
-147
lines changed

3 files changed

+151
-147
lines changed

‎pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@
66

77
<groupId>git.snippet</groupId>
88
<artifactId>algorithm</artifactId>
9-
<version>2025.07.15</version>
9+
<version>2025.08.19</version>
1010

1111
<properties>
12-
<java.version>21</java.version>
12+
<java.version>24</java.version>
1313
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
1414
<project.build.sourceEncoding>${maven.compiler.encoding}</project.build.sourceEncoding>
1515
<project.reporting.outputEncoding>${maven.compiler.encoding}</project.reporting.outputEncoding>

‎src/main/java/grey/algorithm/Code_0028_LeetCode_0215_KthLargestElementInAnArray.java

Lines changed: 0 additions & 145 deletions
This file was deleted.
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
package grey.algorithm.class10_quicksort;
2+
3+
import java.util.Arrays;
4+
import java.util.PriorityQueue;
5+
6+
/**
7+
* 无序数组中求第K大的数,K从1开始算
8+
* <p>
9+
* 测试链接 : https://leetcode.com/problems/kth-largest-element-in-an-array/
10+
* <p>
11+
* <p>
12+
* 方法0. 大根堆 O(N*logK)
13+
*
14+
* <p>
15+
* 方法1. 快排改进 (概率收敛到O(N), 空间复杂度O(1))
16+
*
17+
* <p>
18+
* 方法2. bfprt算法 (严格收敛到O(N),但是空间复杂度O(N))
19+
*/
20+
public class Code_0015_LeetCode_0215_KthLargestElementInAnArray {
21+
public static void main(String[] args) {
22+
int[] arr = { -1, -1 };
23+
System.out.println(findKthLargest(arr, 2));
24+
}
25+
26+
// 快排改进算法(时间复杂度O(N))
27+
public static int findKthLargest(int[] arr, int k) {
28+
// !!!不要陷入如下几个边界的纠结之中
29+
// 1. 这里是 k - 1 还是 k ,
30+
// 2. 从 0 开始还是 从 1 开始,
31+
// 3. 第 k 大还是第 k 小
32+
// 先考虑思路:
33+
// 先不要纠结第K小还是第K大,
34+
// 先把递归函数和partion方法写出来,再用几个例子去判断一下,
35+
// 最后再定主方法是 调用 k 还是 k - 1
36+
return kthMax(arr, 0, arr.length - 1, k - 1);
37+
}
38+
39+
// 第k大,从0开始算,排序改成从大到小
40+
public static int kthMax(int[] arr, int l, int r, int k) {
41+
if (l >= r) {
42+
return arr[l];
43+
}
44+
int randomValue = arr[l + (int) (Math.random() * (r - l + 1))];
45+
int[] range = sortColors(arr, l, r, randomValue);
46+
if (range[0] <= k && range[1] >= k) {
47+
return randomValue;
48+
} else if (range[0] > k) {
49+
return kthMax(arr, l, range[0] - 1, k);
50+
} else {
51+
// arr[range[1]] > k
52+
return kthMax(arr, range[1] + 1, r, k);
53+
}
54+
}
55+
56+
// 从大到小!!!
57+
public static int[] sortColors(int[] arr, int l, int r, int p) {
58+
int s = l - 1;
59+
int e = r + 1;
60+
int i = l;
61+
while (i < e) {
62+
if (arr[i] > p) {
63+
swap(arr, i++, ++s);
64+
} else if (arr[i] == p) {
65+
i++;
66+
} else {
67+
swap(arr, i, --e);
68+
}
69+
}
70+
return new int[] { s + 1, e - 1 };
71+
}
72+
73+
public static void swap(int[] arr, int i, int j) {
74+
int temp = arr[i];
75+
arr[i] = arr[j];
76+
arr[j] = temp;
77+
}
78+
79+
// bfprt算法
80+
public static int findKthLargest1(int[] nums, int k) {
81+
return bfprt(nums, 0, nums.length - 1, k - 1);
82+
}
83+
84+
private static int bfprt(int[] nums, int L, int R, int index) {
85+
if (L == R) {
86+
return nums[L];
87+
}
88+
int pivot = medianOfMedians(nums, L, R);
89+
int[] range = partition(nums, L, R, pivot);
90+
if (index >= range[0] && index <= range[1]) {
91+
return pivot;
92+
} else if (index < range[0]) {
93+
return bfprt(nums, L, range[0] - 1, index);
94+
} else {
95+
return bfprt(nums, range[1] + 1, R, index);
96+
}
97+
}
98+
99+
// 将arr分成每五个元素一组,不足一组的补齐一组
100+
// 对每组进行排序
101+
// 取出每组的中位数,组成一个新的数组
102+
// 对新的数组求其中位数,这个中位数就是我们需要的值
103+
public static int medianOfMedians(int[] arr, int L, int R) {
104+
int size = R - L + 1;
105+
int offSize = size % 5 == 0 ? 0 : 1;
106+
int[] mArr = new int[size / 5 + offSize];
107+
for (int i = 0; i < mArr.length; i++) {
108+
// 每一组的第一个位置
109+
int teamFirst = L + i * 5;
110+
int median = getMedian(arr, teamFirst, Math.min(R, teamFirst + 4));
111+
mArr[i] = median;
112+
}
113+
return bfprt(mArr, 0, mArr.length - 1, (mArr.length - 1) / 2);
114+
}
115+
116+
public static int getMedian(int[] arr, int L, int R) {
117+
Arrays.sort(arr, L, R);
118+
return arr[(R + L) / 2];
119+
}
120+
121+
public static int[] partition(int[] arr, int L, int R, int pivot) {
122+
int less = L - 1;
123+
int more = R + 1;
124+
while (L < more) {
125+
if (arr[L] > pivot) {
126+
swap(arr, L++, ++less);
127+
} else if (arr[L] == pivot) {
128+
L++;
129+
} else {
130+
swap(arr, L, --more);
131+
}
132+
}
133+
return new int[] { less + 1, more - 1 };
134+
}
135+
136+
// 第K大 --> 第 (len - K + 1) 小
137+
// k需要小于nums.length ,否则没有意义
138+
public static int findKthLargest3(int[] nums, int k) {
139+
PriorityQueue<Integer> heap = new PriorityQueue<>();
140+
for (int i = 0; i < k; i++) {
141+
heap.offer(nums[i]);
142+
}
143+
for (int i = k; i < nums.length; i++) {
144+
heap.offer(nums[i]);
145+
heap.poll();
146+
}
147+
return heap.peek();
148+
}
149+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /