数组中的第k个最大元素(几种排序的解法)

这篇博客详细介绍了四种排序算法:快速排序、随机快速排序、快速选择和归并排序。通过代码实现展示了它们的原理和应用,其中随机化策略提升了算法的效率和稳定性。快速排序平均时间复杂度为O(n log n),而归并排序则保证了稳定的排序效果。

leetcode 题号215

  • 快速排序算法
func findKthLargest(nums []int, k int) int {
    quickSort(nums, 0, len(nums)-1)
    return nums[len(nums)-k]
}

func quickSort(nums []int, left, right int) {
    if left >= right { return }
    tmp, i, j := nums[left], left, right
    for i < j {
        for ; i < j && nums[j] > tmp; j-- {}
        nums[i] = nums[j]
        for ; i < j && nums[i] <= tmp; i++ {}
        nums[j] = nums[i]
    }
    nums[i] = tmp
    quickSort(nums, left, i-1)
    quickSort(nums, i+1, right)
}
  • 随机快速排序算法
func findKthLargest(nums []int, k int) int {
    rand.Seed(time.Now().UnixNano())
    randomQuicksort(nums, 0, len(nums)-1)
    return nums[len(nums)-k]
}

func randomQuicksort(nums []int, left, right int) {
    if left >= right { return }
    index := partition(nums, left, right)
    randomQuicksort(nums, left, index-1)
    randomQuicksort(nums, index+1, right)
}

func partition(nums []int, left, right int) int {
    index, small := left + rand.Int() % (right-left+1), left-1
    nums[index], nums[right] = nums[right], nums[index]
    for i := left; i < right; i++ {
        if nums[i] < nums[right] {
            small++
            nums[i], nums[small] = nums[small], nums[i]
        }
    }
    small++
    nums[small], nums[right] = nums[right], nums[small]
    return small
}
  • 快速选择算法
func findKthLargest(nums []int, k int) int {
    rand.Seed(time.Now().UnixNano())
    return quickSelect(nums, 0, len(nums)-1, len(nums)-k)
}

func quickSelect(nums []int, left, right, k int) int {
    index := partition(nums, left, right)
    if index == k {
        return nums[index]
    } else if index < k {
        return quickSelect(nums, index+1, right, k)
    }
    return quickSelect(nums, left, index-1, k)
}

func partition(nums []int, left, right int) int {
    index, small := left + rand.Int() % (right-left+1), left-1
    nums[index], nums[right] = nums[right], nums[index]
    for i := left; i < right; i++ {
        if nums[i] < nums[right] {
            small++
            nums[i], nums[small] = nums[small], nums[i]
        }
    }
    small++
    nums[small], nums[right] = nums[right], nums[small]
    return small
}
  • 归并排序
func findKthLargest(nums []int, k int) int {
    mergeSort(nums, make([]int, len(nums)), 0, len(nums)-1)
    return nums[len(nums)-k]
}

func mergeSort(nums, tmp []int, left, right int) {
    if left >= right { return }
    mid := left + (right-left)>>1
    mergeSort(nums, tmp, left, mid)
    mergeSort(nums, tmp, mid+1, right)
    copy(tmp[left:right+1], nums[left:right+1])
    l, r := left, mid+1
    for i := left; i <= right; i++ {
        if l == mid+1 {
            nums[i], r = tmp[r], r+1
        } else if r == right+1 || tmp[l] <= tmp[r] {
            nums[i], l = tmp[l], l+1
        } else {
            nums[i], r = tmp[r], r+1
        }
    }
    return
}   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值