【力扣】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));
    }
}
相关推荐
江畔柳前堤5 小时前
大语言模型分布式训练:从并行策略到万卡工程的系统梳理
人工智能·分布式·深度学习·算法·目标检测·机器学习·语言模型
Forever Nore6 小时前
LeetCode 4 寻找两个正序数组的中位数 - 二分
算法·leetcode
罗西的思考8 小时前
【OpenClaw具身硬件】MiniClaw 阅读笔记---(1)基础
人工智能·算法·机器学习
蛋先生DX9 小时前
大模型参数存储格式揭秘:BF不是男朋友
深度学习·算法·llm
爱跳舞的烤冷面9 小时前
自学嵌入式第22天(数据结构——哈希)
数据结构·算法·哈希算法
猎嘤一号9 小时前
博弈论(Game Theory)的理论、算法与工程
人工智能·算法·安全·博弈论
月光船幽幽10 小时前
影子模式下保护 logits 不被修改
人工智能·python·算法
马拉AI10 小时前
腾讯开源 Agent 记忆系统,AI“换对话就忘”的问题有了新解法(附安装使用教程)
人工智能·算法·开源·科研
地平线开发者11 小时前
征程6工具链模型X86推理方式说明
算法
地平线开发者11 小时前
【征程6】校准量化中HistogramObserver解析
算法