215. 数组中的第K个最大元素

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

题解

方法二:借助 partition 操作定位到最终排定以后索引为 len - k 的那个元素

以下的描述基于 “快速排序” 算法知识的学习,如果忘记的朋友们可以翻一翻自己的《数据结构与算法》教材,复习一下,partition 过程、分治思想和 “快速排序” 算法的优化。

分析:我们在学习 “快速排序” 的时候,接触的第 1 个操作就是 partition(切分),简单介绍如下:

partition(切分)操作,使得:

对于某个索引 jnums[j] 已经排定,即 nums[j] 经过 partition(切分)操作以后会放置在它 “最终应该放置的地方”;
nums[left]nums[j - 1] 中的所有元素都不大于 nums[j]
nums[j + 1]nums[right]中的所有元素都不小于 nums[j]

在这里插入图片描述

partition(切分)操作总能排定一个元素,还能够知道这个元素它最终所在的位置,这样每经过一次 partition(切分)操作就能缩小搜索的范围,这样的思想叫做 “减而治之”(是 “分而治之” 思想的特例)。

java代码如下:

class Solution {
    public int findKthLargest(int[] nums, int k) {
        int left = 0;
        int right = nums.length -1;
        int pivot = nums[0];
        int target = nums.length - k;

        while(true){
            int index = partition(nums, left, right);

            if (index < target){
                left = index + 1;
            }else if(index > target){
                right = index - 1;
            }else{
                return nums[index];
            }
        }
    }

    public int partition(int[] nums,int left,int right){
        if(left > right){
            return -1;
        }

        int temp = nums[left];
        int i = left;
        int j = right;

        while(i != j){
            while(nums[j] >= temp && j > i){
                j --;
            }

            while(nums[i] <= temp && j > i){
                i ++;
            }

            if(i < j){
                int t = nums[i];
                nums[i] = nums[j];
                nums[j] = t;
            }
        }

        nums[left] = nums[i];
        nums[i] = temp;

        return i;
    }
}

python代码:

class Solution:
    def findKthLargest(self, nums: List[int], k: int) -> int:
        left = 0
        right = len(nums) - 1
        pivot = nums[0]
        target = len(nums) - k

        while True:
            index = self.partition(nums, left, right)

            if index == target:
                return nums[index]
            elif index < target:
                left = index + 1
            elif index > target:
                right = index - 1
    
    def partition(self, nums: List[int], left : int, right: int):
        if left > right:
            return -1
        
        tmp = nums[left]
        i = left
        j = right
        while i != j:
            while j > i and nums[j] >= tmp:
                j = j - 1
            while j > i and nums[i] <= tmp:
                i = i + 1
            
            if i < j:
                nums[i], nums[j] = nums[j], nums[i]
            
        nums[left] = nums[i]
        nums[i] = tmp
        return i
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值