返回

技术指南:运用Go语言之美,轻松解决LeetCode 215. 数组中的第K个最大元素

闲谈

算法精要:

  • 快速排序法:

    • 核心思想:将数组划分为两个部分,左侧部分元素都小于等于轴值,右侧部分元素都大于等于轴值。
    • 递归地对左右两部分数组重复应用快速排序。
    • 时间复杂度:最坏情况为 O(n^2),最好情况为 O(n log n),平均情况为 O(n log n)。
    • 空间复杂度:O(log n)
  • 堆排序法:

    • 核心思想:将数组构建为二叉堆,堆顶元素即为最大元素。
    • 重复删除堆顶元素并重新构建堆,直到堆中只剩一个元素。
    • 时间复杂度:最坏情况和平均情况均为 O(n log n)。
    • 空间复杂度:O(1)

Go语言实现:

package main

import (
    "container/heap"
    "fmt"
    "sort"
)

// 使用快速排序法求解
func findKthLargest_quickSort(nums []int, k int) int {
    // 检查数组是否为空或k是否超出数组长度
    if len(nums) == 0 || k <= 0 || k > len(nums) {
        return 0
    }

    // 调用快速排序
    sort.Slice(nums, func(i, j int) bool {
        return nums[i] > nums[j]
    })

    // 返回第k个最大元素
    return nums[k-1]
}

// 使用堆排序法求解
func findKthLargest_heapSort(nums []int, k int) int {
    // 检查数组是否为空或k是否超出数组长度
    if len(nums) == 0 || k <= 0 || k > len(nums) {
        return 0
    }

    // 将数组构建为二叉堆
    h := &MaxHeap{nums}
    heap.Init(h)

    // 重复删除堆顶元素并重新构建堆,直到堆中只剩一个元素
    for i := 0; i < k-1; i++ {
        heap.Pop(h)
    }

    // 返回堆顶元素
    return h.Peek()
}

// 定义最大堆数据结构
type MaxHeap struct {
    arr []int
}

// 实现堆接口的三个方法
func (h MaxHeap) Len() int {
    return len(h.arr)
}

func (h MaxHeap) Less(i, j int) bool {
    return h.arr[i] > h.arr[j]
}

func (h MaxHeap) Swap(i, j int) {
    h.arr[i], h.arr[j] = h.arr[j], h.arr[i]
}

func (h *MaxHeap) Push(x interface{}) {
    h.arr = append(h.arr, x.(int))
}

func (h *MaxHeap) Pop() interface{} {
    old := h.arr
    n := len(old)
    x := old[n-1]
    h.arr = old[0 : n-1]
    return x
}

// 获取堆顶元素
func (h *MaxHeap) Peek() int {
    return h.arr[0]
}

func main() {
    // 测试快速排序法
    nums1 := []int{3, 2, 1, 5, 6, 4}
    k1 := 2
    fmt.Println("快速排序法:", findKthLargest_quickSort(nums1, k1))

    // 测试堆排序法
    nums2 := []int{3, 2, 1, 5, 6, 4}
    k2 := 3
    fmt.Println("堆排序法:", findKthLargest_heapSort(nums2, k2))
}

结语:

掌握了这两种解题思路和Go语言的实现细节,你将能够轻松应对各种数组排序问题,为LeetCode的征程再添利器。