File tree Expand file tree Collapse file tree 1 file changed +71
-0
lines changed
Expand file tree Collapse file tree 1 file changed +71
-0
lines changed Original file line number Diff line number Diff line change 1+ # 快速选择
2+
3+ ## 使用场景
4+
5+ - 最大/最小的K个数
6+ - 最大/最小的第K个数
7+
8+ ## 算法思路
9+
10+ 和快速排序的思路类似,但是不需要得出精确的比较顺序。首先从数组中随机或指定挑选一个元素作为标志,然后将所有比这个标志小的元素放在左边,比标志大的放在右边,最后会有以下三种可能的情况:
11+
12+ 1 . 这个位置就是K,直接返回即可
13+ 2 . 这个位置小于K,说明K位置的数在右边
14+ 3 . 这个位置大于K,说明K位置的数在左边
15+
16+ ## 算法实现
17+
18+ > [ 215. 数组中的第K个最大元素] ( https://leetcode-cn.com/problems/kth-largest-element-in-an-array/ )
19+ >
20+ > 在未排序的数组中找到第 ** k** 个最大的元素。请注意,需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
21+
22+ ``` java
23+ public int findKthLargest(int [] nums, int k) {
24+ int l = 0 ;
25+ int r = nums. length - 1 ;
26+ while (l < r) {
27+ // 对标志两边分别进行处理
28+ int pivot = partition(nums, l, r);
29+ // 标志就是k
30+ if (pivot == nums. length - k) {
31+ break ;
32+ }
33+ // k位置在标志的右侧
34+ else if (pivot < nums. length - k) {
35+ l = pivot + 1 ;
36+ }
37+ // k位置在标志的左侧
38+ else {
39+ r = pivot - 1 ;
40+ }
41+ }
42+ return nums[nums. length - k];
43+ }
44+
45+ private int partition(int [] nums, int start, int end) {
46+ int l = start;
47+ int r = end + 1 ;
48+ // 选择首元素作为比较标志
49+ // 比标志小的放在左边,比标志大的放在右边
50+ while (true ) {
51+ while (nums[++ l] < nums[start] && l < end);
52+ while (nums[-- r] > nums[start] && r > start);
53+ if (l >= r) {
54+ break ;
55+ }
56+ swap(nums, l, r);
57+ }
58+ // 将标志交换到中间
59+ swap(nums, start, r);
60+ return r;
61+ }
62+
63+ private void swap(int [] nums, int i, int j) {
64+ int temp = nums[i];
65+ nums[i] = nums[j];
66+ nums[j] = temp;
67+ }
68+ ```
69+
70+
71+
You can’t perform that action at this time.
0 commit comments