【力扣】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));
    }
}
相关推荐
hsling松子1 小时前
使用PaddleHub智能生成,献上浓情国庆福
人工智能·算法·机器学习·语言模型·paddlepaddle
dengqingrui1232 小时前
【树形DP】AT_dp_p Independent Set 题解
c++·学习·算法·深度优先·图论·dp
C++忠实粉丝2 小时前
前缀和(8)_矩阵区域和
数据结构·c++·线性代数·算法·矩阵
ZZZ_O^O2 小时前
二分查找算法——寻找旋转排序数组中的最小值&点名
数据结构·c++·学习·算法·二叉树
CV-King3 小时前
opencv实战项目(三十):使用傅里叶变换进行图像边缘检测
人工智能·opencv·算法·计算机视觉
代码雕刻家3 小时前
数据结构-3.9.栈在递归中的应用
c语言·数据结构·算法
雨中rain3 小时前
算法 | 位运算(哈希思想)
算法
Kalika0-05 小时前
猴子吃桃-C语言
c语言·开发语言·数据结构·算法
sp_fyf_20245 小时前
计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-02
人工智能·神经网络·算法·计算机视觉·语言模型·自然语言处理·数据挖掘
我是哈哈hh7 小时前
专题十_穷举vs暴搜vs深搜vs回溯vs剪枝_二叉树的深度优先搜索_算法专题详细总结
服务器·数据结构·c++·算法·机器学习·深度优先·剪枝