【力扣】215. 数组中的第K个最大元素

【力扣】215. 数组中的第K个最大元素

给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。

示例 1:

输入: [3,2,1,5,6,4], k = 2

输出: 5

示例 2:

输入: [3,2,3,1,2,4,5,5,6], k = 4

输出: 4

提示:

1 <= k <= nums.length <= 1 0 5 10^5 105

  • 1 0 4 10^4 104 <= nums[i] <= 1 0 4 10^4 104

题解

堆排序,使用优先队列 PriorityQueue 时间复杂度: O ( N l o g K ) O(NlogK) O(NlogK)

java 复制代码
// https://leetcode.cn/problems/kth-largest-element-in-an-array/
import org.junit.jupiter.api.Test;
import java.util.PriorityQueue;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class Solution {
	//思想:堆排序,
    public int findKthLargest(int[] nums, int k) {
        //优先队列,默认情况下,优先级队列的对象按自然顺序排序
        //PriorityQueue调用remove()或poll()方法,返回的总是优先级最高的元素。
        PriorityQueue<Integer> pq = new PriorityQueue<>();//优先队列保存数值大小的前k个数

        for (int num : nums) {
			pq.add(num);
            //队列长度大于输入的 k
            if (pq.size() > k) {
                pq.poll();
            }
        }
        //System.out.println(pq);
        return pq.peek();   //peek():检索但不删除此队列的头部,如果此队列为空,则返回null。
    }

    //暴力
    public int findKthLargest2(int[] nums, int k) {
        Arrays.sort(nums);
        return nums[nums.length - k];
    }

    @Test
    public void test() {
        Solution s = new Solution();
        assertEquals(5, s.findKthLargest(new int[]{3, 2, 1, 5, 6, 4}, 2));
        assertEquals(4, s.findKthLargest(new int[]{3, 2, 3, 1, 2, 4, 5, 5, 6}, 4));
        assertEquals(3, s.findKthLargest(new int[]{3, 2, 3, 3, 1, 2, 4, 5, 5, 6}, 5));
    }
}

快排:

java 复制代码
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;

// Time Complexity: O(N)
// Space Complexity: O(logN)
class Solution {

    public int findKthLargest(int[] nums, int k) {
        return quickSort(nums, 0, nums.length - 1, k);//起始位置,终止位置
    }

    public int quickSort(int[] nums, int left, int right, int k) {
        // 第 1 大的数,下标是 len - 1;
        // 第 2 大的数,下标是 len - 2;
        // ...
        // 第 k 大的数,下标是 len - k;
        //随机取一个数作为index
        int index = randomParition(nums, left, right);
        //刚好是第k大
        if (index == k - 1) {
            return nums[index];
        }
        else {
            //取的第k大元素在index左边
            if (index > k - 1){
                return quickSort(nums, left, index - 1, k);
            }
            //取的第k大元素在index右边
            else{
                return quickSort(nums, index + 1, right, k);
            }
        }
    }


    public int randomParition(int[] nums, int left, int right) {
        //在[l,r]中随机取一个数
        int i = (int) (Math.random() * (right - left)) + left;
        //交换的目的是:将随机取出来的值,先移动到数组的尾端,然后将该值前面的数分区,此时的nums[i]为快排的pivot
        swap(nums, i, right);
        //进行分区
        return partition(nums, left, right);
    }

    public void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }

    //分区函数,比元素小的放右边,大的放左边
    public int partition(int[] nums, int left, int right) {
        //随机取出的数
        int pivot = nums[right];
        //记录最右边位置
        int rightmost = right;


        while (left <= right) {
            while (left <= right && nums[left] > pivot) {
                left++;
            }
            while (left <= right && nums[right] <= pivot) {
                right--;
            }
            if (left <= right) {
                swap(nums, left, right);
            }
        }

        swap(nums, left, rightmost);
        return left;//分界线的值
    }

    @Test
    public void test() {
        Solution s = new Solution();
        assertEquals(5, s.findKthLargest(new int[]{3, 2, 1, 5, 6, 4}, 2));
        assertEquals(4, s.findKthLargest(new int[]{3, 2, 3, 1, 2, 4, 5, 5, 6}, 4));
        assertEquals(3, s.findKthLargest(new int[]{3, 2, 3, 3, 1, 2, 4, 5, 5, 6}, 5));
    }
}
相关推荐
浊酒南街35 分钟前
决策树python实现代码1
python·算法·决策树
冠位观测者2 小时前
【Leetcode 热题 100】208. 实现 Trie (前缀树)
数据结构·算法·leetcode
小王爱吃月亮糖3 小时前
C++的23种设计模式
开发语言·c++·qt·算法·设计模式·ecmascript
IT猿手5 小时前
最新高性能多目标优化算法:多目标麋鹿优化算法(MOEHO)求解LRMOP1-LRMOP6及工程应用---盘式制动器设计,提供完整MATLAB代码
开发语言·算法·matlab·智能优化算法·多目标算法
InfiSight智睿视界6 小时前
AI 技术,让洗护行业焕然「衣」新
人工智能·算法
程序员一诺6 小时前
【机器学习】嘿马机器学习(算法篇)第11篇:决策树算法,学习目标【附代码文档】
人工智能·python·算法·机器学习
Evand J6 小时前
平方根无迹卡尔曼滤波(SR-UKF)算法,用于处理三维非线性状态估计问题
算法
taoyong0016 小时前
代码随想录算法训练营第十五天-二叉树-110.平衡二叉树
数据结构·算法
-芒果酱-6 小时前
k-Means聚类算法 HNUST【数据分析技术】(2025)
算法·kmeans·聚类
渣渣威的仿真秀6 小时前
Jensen-Shannon Divergence:定义、性质与应用
人工智能·算法·概率论