leetcode回顾——Kth Largest Element in an Array

题目

1
2
3
4
5
6
7
8
9
10
11
12
13
在未排序的数组中找到第 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 ≤ 数组的长度。

AC代码

二分查找的实现

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
func findKthLargest(nums []int, k int) int {
t := nums[0]
all := true
for i := 1; i < len(nums); i ++ {
if t != nums[i] {
all = false
break
}
}
if all {
return t
}
right := 65535
left := -65535
for left < right {
mid := (left + right) / 2
kth, sames, ok := minTh(nums, mid)
if kth <= k && k <= kth + sames && ok {
return mid
}
if kth > k {
left = mid + 1
} else {
right = mid - 1
}
}
return left
}

func minTh(nums []int, target int) (int, int, bool) {
a := 0
b := 0
k := false
for i := 0; i < len(nums); i ++ {
if nums[i] > target {
a ++
}
if nums[i] == target {
b ++
k = true
}
}
if b != 0 {
b --
}
return a + 1, b, k
}

快速选择的实现

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
func findKthLargest(nums []int, k int) int {
QuickChoose(&nums, 0, len(nums) - 1, k - 1)
return nums[k - 1]
}

func QuickChoose(nums *[]int, start, end, k int) {
if start < end {
i, j := start, end
mid := (*nums)[(i + j) / 2]
for i <= j {
for (*nums)[i] > mid {
i ++
}
for (*nums)[j] < mid {
j --
}
if i <= j {
(*nums)[i], (*nums)[j] = (*nums)[j], (*nums)[i]
i++
j--
}
}
if k <= j {
QuickChoose(nums, start, j, k)
} else if k >= i {
QuickChoose(nums, i, end, k)
}
}
}