[Swift]LeetCode215. 数组中的第K个最大元素 | Kth Largest Element in an Array

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

➤微信公众号:山青咏芝(shanqingyongzhi)

➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/

➤GitHub地址:https://github.com/strengthen/LeetCode

➤原文地址:https://www.cnblogs.com/strengthen/p/10197956.html

➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。

➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

热烈欢迎,请直接点击!!!

进入博主App Store主页,下载使用各个作品!!!

注:博主将坚持每月上线一个新app!!!

Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element.

Example 1:

Input: [3,2,1,5,6,4] and k = 2
Output: 5

Example 2:

Input: [3,2,3,1,2,4,5,5,6] and k = 4
Output: 4

Note:

You may assume k is always valid, 1 ≤ k ≤ array's length.


在未排序的数组中找到第 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 ≤ 数组的长度。


24ms

1 class Solution {
2     func findKthLargest(_ nums: [Int], _ k: Int) -> Int {
3         return nums.sorted(by: >)[k - 1]
4     }
5 }

56ms

 1 class Solution {
 2     func findKthLargest(_ nums: [Int], _ k: Int) -> Int {
 3       var newNums = nums
 4         buildMaxHead(&newNums)//建最大堆
 5         for i in ((newNums.count - k - 1)..<newNums.count).reversed() {
 6             swap(&newNums, 0, i)
 7             if i == newNums.count - k {
 8                 return newNums[i]
 9             }
10             headify(&newNums, 0, i)
11         }
12         return 0
13     }
14     //MARK: 堆排序
15     func headSort(_ nums:inout [Int]) {
16         buildMaxHead(&nums)
17         for i in (1..<nums.count).reversed() {
18             swap(&nums, i, 0)
19             headify(&nums, 0, i)
20         }
21     }
22     //建最大堆
23     func buildMaxHead(_ nums:inout [Int]) {
24         for i in (0...nums.count/2).reversed() {
25             headify(&nums, i,nums.count)
26         }
27     }
28     //堆调整
29     func headify(_ nums:inout [Int], _ index: Int, _ length: Int) {
30         let leftChild = index * 2 + 1 // index节点的左孩子节点
31         let rightChild = index * 2 + 2 //index节点的右孩子节点
32         var largertIndex = index //节点与左右孩子的最大值
33         if leftChild < length && nums[leftChild] > nums[largertIndex] {
34             largertIndex = leftChild
35         }
36         if rightChild < length && nums[rightChild] > nums[largertIndex] {
37             largertIndex = rightChild
38         }
39         //如果交换了
40         if largertIndex != index {
41             swap(&nums, largertIndex, index)//交换节点值
42             headify(&nums, largertIndex,length)//调整变动的节点
43         }
44     }
45         func swap(_ nums:inout [Int],_ i:Int,_ j: Int) {
46         let temp = nums[i]
47         nums[i] = nums[j]
48         nums[j] = temp
49     }
50 }

56ms

 1 class Solution {
 2     func findKthLargest(_ nums: [Int], _ k: Int) -> Int {
 3         var nums = nums
 4         return find(&nums, 0, nums.count - 1, k)
 5     }
 6 
 7     func find(_ nums: inout [Int], _ start: Int, _ end: Int, _ k: Int) -> Int {
 8         let pivot = partition(&nums, start, end)
 9         let j = nums.count - pivot
10         if j > k {
11             return find(&nums, pivot + 1, end, k)
12         }
13         if j == k {
14             return nums[pivot]
15         }
16         return find(&nums, start, pivot - 1, k)
17     }
18 
19     func partition(_ nums: inout [Int], _ start: Int, _ end: Int) -> Int {
20         guard start < end else {
21             return start
22         }
23         let pivot = Int.random(in: start...end)
24         nums.swapAt(pivot, end)
25         var index = start
26         for i in start..<end where nums[i] < nums[end] {
27             nums.swapAt(i, index)
28             index += 1
29         }
30         nums.swapAt(index, end)
31         return index
32     }
33 }

60ms

 1 class Solution {
 2     func findKthLargest(_ nums: [Int], _ k: Int) -> Int {
 3         var arr = nums
 4         return quickselect(arr: &arr, start: 0, end: arr.count - 1, k: arr.count - k)
 5     }
 6    
 7     private func quickselect(arr: inout[Int], start: Int, end: Int, k: Int) -> Int {
 8         let pivot = partition(arr: &arr, start: start, end: end)
 9         if pivot > k { return quickselect(arr: &arr, start: start, end: pivot - 1, k: k) }
10         if pivot == k { return arr[pivot] }
11         return quickselect(arr: &arr, start: pivot + 1, end: end, k: k)
12     }
13 
14     private func partition(arr: inout[Int], start: Int, end: Int) -> Int {
15         guard start < end else { return start }
16         
17         var i = start
18         let pivotIndex = Int.random(in: start ... end)
19         let pivot  = arr[pivotIndex]
20         (arr[pivotIndex], arr[end]) = (arr[end], arr[pivotIndex])
21         
22         for j in start ..< end {
23             if arr[j] < pivot {
24                 (arr[i], arr[j]) = (arr[j], arr[i])
25                 i += 1
26             }
27         }
28         
29         (arr[i], arr[end]) = (arr[end], arr[i])
30         return i
31     }
32     
33 }

84ms

 1 class Solution {
 2     private var heapSize = 0
 3     
 4     func findKthLargest(_ nums: [Int], _ k: Int) -> Int {
 5         guard nums.count > 0 else {
 6             return 0
 7         }
 8         var nums = nums
 9         buildMaxHeap(&nums)
10         var i = 0
11         while i < k - 1 {
12             swap(&nums, 0, heapSize - 1)
13             heapSize -= 1
14             maxHeapAdjust(&nums, 0)
15             i += 1
16         }
17         return nums[0]
18     }
19     
20     func buildMaxHeap(_ nums: inout [Int]) {
21         heapSize = nums.count
22         var i = heapSize >> 1 - 1
23         while i >= 0 {
24             maxHeapAdjust(&nums, i)
25             i -= 1
26         }
27     }
28     
29     func maxHeapAdjust(_ nums: inout [Int],_ index: Int) {
30         var largest = index
31         var l = index << 1 + 1
32         var r = index << 1 + 2
33         if l < heapSize && nums[l] > nums[largest] {
34             largest = l
35         }
36         if r < heapSize && nums[r] > nums[largest] {
37             largest = r
38         }
39         if largest != index {
40             swap(&nums, largest, index)
41             maxHeapAdjust(&nums, largest)
42         }
43     }
44     
45     func swap(_ nums: inout [Int], _ i: Int,_ j: Int) {
46         let temp = nums[i]
47         nums[i] = nums[j]
48         nums[j] = temp
49     }
50 }