【力扣】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));
    }
}
相关推荐
电鱼智能的电小鱼4 小时前
基于电鱼 AI 工控机的智慧工地视频智能分析方案——边缘端AI检测,实现无人值守下的实时安全预警
网络·人工智能·嵌入式硬件·算法·安全·音视频
孫治AllenSun4 小时前
【算法】图相关算法和递归
windows·python·算法
格图素书5 小时前
数学建模算法案例精讲500篇-【数学建模】DBSCAN聚类算法
算法·数据挖掘·聚类
DashVector6 小时前
向量检索服务 DashVector产品计费
数据库·数据仓库·人工智能·算法·向量检索
AI纪元故事会6 小时前
【计算机视觉目标检测算法对比:R-CNN、YOLO与SSD全面解析】
人工智能·算法·目标检测·计算机视觉
夏鹏今天学习了吗6 小时前
【LeetCode热题100(59/100)】分割回文串
算法·leetcode·深度优先
卡提西亚6 小时前
C++笔记-10-循环语句
c++·笔记·算法
还是码字踏实6 小时前
基础数据结构之数组的双指针技巧之对撞指针(两端向中间):三数之和(LeetCode 15 中等题)
数据结构·算法·leetcode·双指针·对撞指针
Coovally AI模型快速验证8 小时前
当视觉语言模型接收到相互矛盾的信息时,它会相信哪个信号?
人工智能·深度学习·算法·机器学习·目标跟踪·语言模型
电院工程师9 小时前
SIMON64/128算法Verilog流水线实现(附Python实现)
python·嵌入式硬件·算法·密码学