zoukankan      html  css  js  c++  java
  • [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 
    ➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
    ➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

    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 }
  • 相关阅读:
    原码, 反码, 补码的基础概念和计算方法.
    QoS in RoCE
    TCP拥塞控制算法之NewReno和SACK
    intel xeon家族介绍
    Intel 处理器架构演进 转
    IP报文头详解
    高性能网络服务器编程:为什么linux下epoll是最好,Netty要比NIO.2好?
    tcp拥塞控制 tahoe reno new reno sack
    TCP/IP详解--拥塞控制 慢启动 快恢复 拥塞避免
    LTTng 简介&使用实战
  • 原文地址:https://www.cnblogs.com/strengthen/p/10197956.html
Copyright © 2011-2022 走看看