【LeetCode215】数组中的第K个最大元素【快排 堆排】

本文详细介绍了如何使用快速排序和堆排序算法来找出未排序数组中的第K个最大元素。通过具体示例展示了算法的实现过程,并提供了AC代码供读者参考。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

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

思路

1.快排:1.获取中轴 2.左边递归 3.右边递归

2.堆排

代码

1.快排

class Solution {
    public int findKthLargest(int[] nums, int k) {
            //递归  找中轴  左边递归  右边递归
        quickSort(nums,0,nums.length-1);
        return nums[nums.length-k];
    }
    public void quickSort(int[] nums,int low,int high){
        while(low<high){
            int mid = getMid(nums,low,high);
            quickSort(nums,low,mid);
            quickSort(nums,mid+1,high);
        } 
    }
    //找中轴
    public int getMid(int[] nums,int low,int high){
        int i=low;
        int j=high;
        int tmp = nums[i];//把第一个位置空出来并赋值到tmp;然后从右到左判断;赋值,再从左到右判断 赋值;
        while(i<j){
            while(i<j&&nums[j]>=tmp) j--;
            if(i<j) {
                nums[i]=nums[j];
                i++;
            }
            while(i<j&&nums[i]<=tmp) i++;
            if(i<j){
                nums[j]=nums[i];
                j--;
            }
        }
        if(i==j){
            nums[i]=tmp;
        }
        return i; 
    }


}

2.快排的基本思想

public class QuickSort {

#arr 需要排序的数组
#low 开始时最左边的索引=0
#high 开始时最右边的索引=arr.length-1
    public static void quickSort(int[] arr,int low,int high){
        int i,j,temp,t;
        if(low>high){
            return;
        }
        i=low;#左边哨兵的索引
        j=high;#右边哨兵的索引
        //temp就是基准位
        temp = arr[low];#以最左边为  基准位

        while (i<j) {
            //先看右边,依次往左递减
            #先从右往左找一个小于 基准位的数
            #当右边的哨兵位置所在的数>基准位的数 时
            #继续从右往左找(同时 j 索引-1)
            #找到后会跳出 while循环
            while (temp<=arr[j]&&i<j) {
                j--;
            }

            //再看左边,依次往右递增
            #步骤和上面类似
            while (temp>=arr[i]&&i<j) {
                i++;
            }

            //如果满足条件则交换
            if (i<j) {

#z、y 都是临时参数,用于存放 左右哨兵 所在位置的数据
                 z = arr[i];
                 y = arr[j];

                 # 左右哨兵 交换数据(互相持有对方的数据)
                 arr[i] = y;
                 arr[j] = z;

            }

        }

#这时 跳出了 “while (i<j) {}” 循环
#说明 i=j 左右在同一位置
        //最后将基准为与i和j相等位置的数字交换
         arr[low] = arr[i];#或 arr[low] = arr[j];
         arr[i] = temp;#或 arr[j] = temp;


#i=j
#这时  左半数组<(i或j所在索引的数)<右半数组
#也就是说(i或j所在索引的数)已经确定排序位置, 所以就不用再排序了,
# 只要用相同的方法 分别处理  左右数组就可以了

        //递归调用左半数组
        quickSort(arr, low, j-1);
        //递归调用右半数组
        quickSort(arr, j+1, high);
    }


    public static void main(String[] args){
        int[] arr = {10,7,2,4,7,62,3,4,2,1,8,9,19};
        quickSort(arr, 0, arr.length-1);
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }
}

3.解决:AC代码 参考:https://blog.csdn.net/qq_41645636/article/details/99342495
基本快排步骤
1.
在这里插入图片描述

class Solution {
    public int findKthLargest(int[] nums, int k) {
        quickSort(nums, 0, nums.length - 1);
        return nums[nums.length - k];
    }
    
    private void quickSort(int[] nums, int low, int high) {
        if(nums == null || nums.length == 0 || low >= high) {
            return;
        }
        int basic = nums[low];
        int i = low, j = high;
        while(i < j) {
            while(j > i && nums[j] >= basic) {
                j --;
            }
            while(i < j && nums[i] <= basic) {
                i ++;
            }
            if(i < j) {
                swap(nums, i, j);
            }
            
        }
        nums[low] = nums[i];
        nums[i] = basic;
        quickSort(nums, low, i - 1);
        quickSort(nums, i + 1, high);
    }
    
    private void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
}

总结

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值