【力扣】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 <= numsi <= 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));
    }
}
相关推荐
南境十里·墨染春水7 小时前
C++ 工厂模式:从入门到进阶,彻底掌握对象创建的艺术
开发语言·c++·算法
@insist1237 小时前
系统架构设计师-实时性评价、调度算法与内核架构选型
算法·架构·系统架构·软考·系统架构设计师·软件水平考试
一只齐刘海的猫12 小时前
【Leetcode】找到字符串中所有字母异位词
算法·leetcode·职场和发展
海清河晏11113 小时前
数据结构 | 八大排序
数据结构·算法·排序算法
IronMurphy14 小时前
【算法五十七】146. LRU 缓存
算法·缓存
凌波粒14 小时前
LeetCode--108.将有序数组转换为二叉搜索树(二叉树)
算法·leetcode·职场和发展
liulilittle14 小时前
KCC:在 BBR 思路上的一次探索
网络·tcp/ip·算法·bbr·通信·拥塞控制·kcc
浦信仿真大讲堂15 小时前
达索系统SIMULIA Abaqus 2026接触和约束的增强新功能介绍
人工智能·python·算法·仿真软件·达索软件
点云侠15 小时前
PCL 生成三棱锥点云
c++·算法·最小二乘法