Skip to content

Commit 1a3d928

Browse files
committed
四刷215
1 parent 5af2984 commit 1a3d928

File tree

4 files changed

+94
-17
lines changed

4 files changed

+94
-17
lines changed

docs/0000-08-quickselect.adoc

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,21 @@
11
[#0000-08-quickselect]
22
= QuickSelect 快速选择
33

4+
快速选择起源于快排算法。在快排算法中,把元素根据基准元素分成左右两部分,一边的元素小于基准元素,另外一个的元素大于等于基准元素,再对两边的元素递归处理,最终得到有序结果。受此启发,在将元素根据基准元素分成左右两部分后,这里假设,左边小于基准元素,右边大于等于基准元素,那么会有如下三种情况:
5+
6+
. 当前基准元素所在位置正好是 K,正好是所求结果,直接返回;
7+
. 当前基准元素所在位置小于 K,那么 K 位置在当前基准元素的右边;
8+
. 当前基准元素所在位置大于 K,那么 K 位置在当前基准元素的左边;
9+
10+
所以,该模式不仅适用于求第 K 个之最元素,也适用于求“Top K 问题”。
11+
12+
413
== 经典题目
514

615
. xref:0215-kth-largest-element-in-an-array.adoc[215. Kth Largest Element in an Array]
16+
. xref:0324-wiggle-sort-ii.adoc[324. Wiggle Sort II]
17+
. xref:0347-top-k-frequent-elements.adoc[347. 前 K 个高频元素]
18+
. xref:0973-k-closest-points-to-origin.adoc[973. K Closest Points to Origin]
19+
. xref:1738-find-kth-largest-xor-coordinate-value.adoc[1738. Find Kth Largest XOR Coordinate Value]
20+
. xref:1985-find-the-kth-largest-integer-in-the-array.adoc[1985. Find the Kth Largest Integer in the Array]
21+
. xref:2343-query-kth-smallest-trimmed-number.adoc[2343. Query Kth Smallest Trimmed Number]

docs/0215-kth-largest-element-in-an-array.adoc

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,32 @@
11
[#0215-kth-largest-element-in-an-array]
2-
= 215. Kth Largest Element in an Array
2+
= 215. 数组中的第K个最大元素
33

4-
{leetcode}/problems/kth-largest-element-in-an-array/[LeetCode - Kth Largest Element in an Array^]
4+
https://leetcode.cn/problems/kth-largest-element-in-an-array/[LeetCode - 215. 数组中的第K个最大元素 ^]
55

6-
Find the *k*th largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element.
6+
给定整数数组 `nums` 和整数 `k`,请返回数组中第 *`k`* 个最大的元素。
77

8-
*Example 1:*
8+
请注意,你需要找的是数组排序后的第 `k` 个最大的元素,而不是第 `k` 个不同的元素。
99

10-
[subs="verbatim,quotes,macros"]
11-
----
12-
*Input:* `[3,2,1,5,6,4] `and k = 2
13-
*Output:* 5
10+
你必须设计并实现时间复杂度为 stem:[O(n)] 的算法解决此问题。
1411

15-
----
12+
*示例 1:*
1613

17-
*Example 2:*
14+
....
15+
输入: [3,2,1,5,6,4], k = 2
16+
输出: 5
17+
....
1818

19-
[subs="verbatim,quotes,macros"]
20-
----
21-
*Input:* `[3,2,3,1,2,4,5,5,6] `and k = 4
22-
*Output:* 4
23-
----
19+
*示例 2:*
2420

25-
*Note: *
21+
....
22+
输入: [3,2,3,1,2,4,5,5,6], k = 4
23+
输出: 4
24+
....
2625

26+
*提示:*
2727

28-
You may assume k is always valid, 1 ≤ k ≤ array's length.
28+
* `1 \<= k \<= nums.length \<= 10^5^`
29+
* `-10^4^ \<= nums[i] \<= 10^4^`
2930
3031
== 思路分析
3132

@@ -64,6 +65,15 @@ include::{sourcedir}/_0215_KthLargestElementInAnArray_2.java[tag=answer]
6465
include::{sourcedir}/_0215_KthLargestElementInAnArray_3.java[tag=answer]
6566
----
6667
--
68+
69+
四刷::
70+
+
71+
--
72+
[{java_src_attr}]
73+
----
74+
include::{sourcedir}/_0215_KthLargestElementInAnArray_4.java[tag=answer]
75+
----
76+
--
6777
====
6878

6979
== 参考资料

logbook/202503.adoc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,11 @@ endif::[]
7070
|{doc_base_url}/0347-top-k-frequent-elements.adoc[题解]
7171
|✅ Top K 问题,优先队列;桶排序
7272

73+
|{counter:codes2503}
74+
|{leetcode_base_url}/kth-largest-element-in-an-array/[215. Kth Largest Element in an Array^]
75+
|{doc_base_url}/0215-kth-largest-element-in-an-array.adoc[题解]
76+
|⭕️ 快速选择,想清楚边界情况!
77+
7378
|===
7479

7580
截止目前,本轮练习一共完成 {codes2503} 道题。
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package com.diguage.algo.leetcode;
2+
3+
public class _0215_KthLargestElementInAnArray_4 {
4+
// tag::answer[]
5+
/**
6+
* @author D瓜哥 · https://www.diguage.com
7+
* @since 2025-03-26 16:24:19
8+
*/
9+
public int findKthLargest(int[] nums, int k) {
10+
return quickselect(nums, nums.length - k, 0, nums.length - 1);
11+
}
12+
13+
private int quickselect(int[] nums, int k, int left, int right) {
14+
if (left == right) {
15+
return nums[k];
16+
}
17+
int pivot = nums[left];
18+
// 由于下面先移动指针,所以左右指针各项左右移一位
19+
int l = left - 1, r = right + 1;
20+
while (l < r) {
21+
// 交换之后,没有移动指针,所以先移动指针再循环
22+
do {
23+
l++;
24+
} while (nums[l] < pivot);
25+
do {
26+
r--;
27+
} while (pivot < nums[r]);
28+
if (l < r) {
29+
int tmp = nums[l];
30+
nums[l] = nums[r];
31+
nums[r] = tmp;
32+
}
33+
}
34+
// r 是最后一个小于或等于 pivot 的元素的索引。
35+
// [left, r] 是确定小于或等于 pivot 的部分。
36+
if (k <= r) {
37+
return quickselect(nums, k, left, r);
38+
} else {
39+
return quickselect(nums, k, r + 1, right);
40+
}
41+
}
42+
// end::answer[]
43+
44+
public static void main(String[] args) {
45+
new _0215_KthLargestElementInAnArray_4().findKthLargest(new int[]{3, 2, 1, 5, 6, 4}, 2);
46+
}
47+
}

0 commit comments

Comments
 (0)