leetcode215数组中的第K个最大元素

快排简介

快排即为快速排序算法,其的速度是相较于其他排序算法最快的

快排的思想

  1. 每次在区间中选择一个pivot,也就是作为分界点
  2. 将小于它的放它的左边,将大于它的分到它的右边
  3. 如果区间的l和r相等则返回

快排代码

public static void quickSort(int l,int r){
        if(r==l)return;
        int mid=arr[(l+r)/2];
        int i=l-1;
        int j=r+1;
        while(i<j){
            while(arr[++i]<mid){}
            while(arr[--j]>mid){}
            if(i<j){
                int t=arr[i];
                arr[i]=arr[j];
                arr[j]=t;
            }
        }
        quickSort(l,j);
        quickSort(j+1,r);
    }

快排题目

裸题:排序数组 - 提交记录 - 力扣(LeetCode)

更近一步:215. 数组中的第K个最大元素 - 力扣(LeetCode)

这里主要详细讲的就是更近一步的题目:

关键点:需要时间复杂度为:O(n),也就是我们使用原生的快排进行排序后是会超时的

所以我们需要改变思路:

快排的时间复杂度为O(nlogn)这个logn是由于我们分为两个部分后两个部分都要处理,如果只负责一个部分即可

那么我们的解决思路如下:

我们在一次快排时,总能确定下pivot的位置,那么我们就根据当前pivot的位置是否符合nums.length-k,来划分

值得一提的是:我们模板题的划分是

​ quickSort(l,j);
​ quickSort(j+1,r);

那么我们这个j是否就意味着对应的pivot分配后的位置呢?以及如果他是的话?我们是不是直接返回就好了?

首先j并不是pivot分配后的值,理由如下:

  1. 在while流程内我们pivot第一个会进行更改位置,如果正常进行更改位置,且会再次进入到while中,那么j是会直接跳过上次把pivot换到的j这个位置的所以基本上不可行

所以我们不能采取这样的措施,那么我们怎么利用这个快排来得到我们的答案呢?

其实这个过程有点类似二分的思想,在我们while后被分成了两批,也就是左部分,以及右部分,在这之中,我们的左部分符合的条件是<pivot,而右部分是大于pivot的,所以我们通过dfs来相当于二分这个区间,且第k大的元素必然存在,当区间缩减为只有一个元素时,则为最终的答案

代码部分

class Solution {
    public int findKthLargest(int[] nums, int k) {
            //快排秒了
            return quickSort(nums,nums.length-k,0,nums.length-1);
    }
    public int quickSort(int []nums,int k,int l,int r){
        //我们只划分两边然后在剩下的两个区间中只会接着处理其中一个
        //如果<=k,那么处理>k的那段,否则处理>k的那段
        if(r==l)return nums[k];
        int p=nums[l];
        int i=l-1;
        int j=r+1;
        while(i<j){
            while(nums[++i]<p){}
            while(nums[--j]>p){}
            if(i<j){
                int t=nums[j];
                nums[j]=nums[i];
                nums[i]=t;
            }
        }
        if(j>=k){
            return quickSort(nums,k,l,j);
        }else{
            return quickSort(nums,k,j+1,r);
        }
    }
}
posted @   海山了-  阅读(4)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
点击右上角即可分享
微信分享提示