LeetCode215. 数组中第K个最大元素Golang版

LeetCode215. 数组中第K个最大元素Golang版

1. 问题描述

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

2. 思路

2.1. 思路1 冒泡排序(冒K次泡)

  1. 外层循环,用变量i 控制循环k次

    1.1. 冒泡,将最大的数替换到数组倒数第i的位置
  2. nums[len(nums) - k]

2.2. 思路2 快排(分区思想)

  1. 快排思想,每一轮快排都会使得下标pivot对应的值,左边的值全小于nums[pivot]
    右边的值全大于nums[pivot]
  2. 令倒数第k个值对应的下标 targetIndex = len(nums) - k
  3. 执行无限循环

    3.1. 分区,拿到返回值index

    3.2. 如果 index == targetIndex,返回index位置对应的值

    3.2. 如果 index < targetIndex,分区左边界右移

    3.3. 如果 index > targetIndex,分区有边界左移

2.3. 思路3

不讲武德的做法

  1. 库函数对数组排序
  2. 返回排序后数组,倒数第5个元素

3. 代码

3.1. 思路1代码

func findKthLargest(nums []int, k int) int {
    var res int

    // 冒泡,总共冒k次,注意边界
    for j := len(nums) - 1; j >= len(nums) - k; j-- {
        for i := 0; i < j; i++ {
            if nums[i] > nums[i + 1] {
                nums[i], nums[i+1] = nums[i+1], nums[i]
            }
        }
        res = nums[j]
    }
    return res
}

3.2. 思路2 代码

func findKthLargest(nums []int, k int) int {
    indexTarget := len(nums) - k
    left, right := 0, len(nums) - 1

    for true {
        index := partition(nums, left, right)
        
        if index == indexTarget {
            return nums[index]
        } else if index < indexTarget {
            left = index + 1
        } else {
            right = index - 1
        }
    }
    return -1
}

// 快排,分区思想
func partition(nums []int, l, r int) int {
    pivot := nums[l]

    for l < r {
        for l < r && nums[r] >= pivot {
            r--
        } 
        nums[l] = nums[r]

        for l < r && nums[l] <= pivot {
            l++
        }
        nums[r] = nums[l]
    }
    nums[l] = pivot
    return l
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值