1.题目描述

215. 数组中的第K个最大元素

在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

示例 1:

1
2
输入: [3,2,1,5,6,4] 和 k = 2
输出: 5

示例 2:

1
2
输入: [3,2,3,1,2,4,5,5,6] 和 k = 4
输出: 4

说明:

你可以假设 k 总是有效的,且 1 ≤ k ≤ 数组的长度。

2.代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
class Solution {
/**
* 返回数组中第k大的数值
* @param nums
* @param k
* @return
*/
public static int findKthLargest(int[] nums, int k) {
//排序
mergeSort(nums,0,nums.length-1);

return nums[nums.length-k];
}

/**
* 归并排序 递归
* @param nums
* @param start
* @param end
*/
public static void mergeSort(int[] nums,int start,int end){
//只要划分的区间长度仍然不为1
if (start != end){
int middle = (start+end) / 2;

//分
mergeSort(nums,start,middle);
mergeSort(nums,middle+1,end);

//治
merge(nums,start,end,middle);
}
}

/**
* 归并
* @param nums
* @param start
* @param end
* @param middle
*/
public static void merge(int[] nums,int start,int end,int middle){
//模拟第一个序列的头指针
int i = start;

//模拟第二个序列的头指针
int j = middle+1;

//模拟临时数组的头指针
int t = 0;

//创建临时数组
int[] temp = new int[end-start+1];

//从头比较两个序列,小的放入临时数组temp
while (i <= middle && j <= end){
//比较大小
if (nums[i] < nums[j]){
//前一个序列
temp[t++] = nums[i++];
}else {
//后一个序列
temp[t++] = nums[j++];
}
}

//单独处理没有处理完的第一个序列
while (i <= middle){
temp[t++] = nums[i++];
}

//单独处理没有处理完的第二个序列
while (j <= end){
temp[t++] = nums[j++];
}

//将临时数组的值赋值到原数组
for (int p = 0; p < temp.length; p++) {
nums[start+p] = temp[p];
}
}
}