数组算法之【数组中第K个最大元素】

目录

LeetCode-215题


LeetCode-215题

给定整数数组nums和整数k,返回数组中第k个最大元素

java 复制代码
public class Solution {
    /**
     * 这里是基于小顶堆这种数据结构来实现的
     */
    public int findKthLargest(int[] nums, int k) {
        // 实例化一个小顶堆
        MinHeap minHeap = new MinHeap(k);

        // 往小顶堆中添加k个元素
        for (int i = 0; i < k; i++) {
            minHeap.offer(nums[i]);
        }

        // 添加k个元素之后
        for (int i = k; i < nums.length; i++) {
            // 遇到不大于堆顶元素的直接跳过不管,继续下一个
            if (nums[i] <= minHeap.peek()) {
                continue;
            }
            // 遇到大于堆顶元素的就将其把堆顶元素替换
            minHeap.replace(nums[i]);
        }

        // 此时堆顶元素就是第k个最大元素
        return minHeap.peek();
    }

    /**
     * 自定义一个小顶堆
     */
    private static class MinHeap {
        private final int[] container;
        private int size;

        public MinHeap(int capacity) {
            container = new int[capacity];
        }

        /**
         * 添加元素
         */
        public boolean offer(int num) {
            if (size == container.length)
                return false;
            // 执行上浮操作
            siftUp(num);
            return true;
        }

        /**
         * 上浮
         */
        private void siftUp(int num) {
            int child = size++;
            // 通过子节点找父节点位置
            int parent = (child - 1) >> 1;
            // 只要满足条件就一直找并比较
            while (child > 0 && container[parent] > num) {
                container[child] = container[parent];
                child = parent;
                parent = (child - 1) >> 1;
            }
            // 新添加的元素放到合适的位置
            container[child] = num;
        }

        /**
         * 替换顶部元素
         */
        public void replace(int num) {
            container[0] = num;
            // 执行下潜操作
            siftDown(0);
        }

        /**
         * 下潜
         */
        private void siftDown(int parent) {
            // 通过父节点位置找左子节点和右子节点的位置
            int left = (parent << 1) + 1;
            int right = left + 1;

            // 只要满足有任一子节点的值小于父节点的值就交换顺序
            int min = parent;
            if (left < size && container[left] < container[min]) {
                min = left;
            }
            if (right < size && container[right] < container[min]) {
                min = right;
            }
            if (min != parent) {
                swap(parent, min);
                siftDown(min);
            }
        }

        /**
         * 交换i位置和j位置上的值
         */
        private void swap(int i, int j) {
            if (i == j)
                return;
            container[i] = container[i] ^ container[j];
            container[j] = container[i] ^ container[j];
            container[i] = container[i] ^ container[j];
        }

        /**
         * 查看堆顶元素
         */
        public int peek() {
            return container[0];
        }
    }
}
相关推荐
遗憾是什么.4 分钟前
数据结构 -- 栈
数据结构·算法·链表
清风er5 分钟前
智能座舱开发
算法·计算机视觉
dragoooon3410 分钟前
[Linux——Lesson23.线程概念与控制:线程基础]
java·开发语言·jvm
带刺的坐椅19 分钟前
Solon Web 的“分身术”:单应用多端口监听,化身多重服务
java·web·solon·端口·单体多模块
Learn Beyond Limits28 分钟前
Data Mining Tasks|数据挖掘任务
人工智能·python·神经网络·算法·机器学习·ai·数据挖掘
装不满的克莱因瓶35 分钟前
【项目亮点】基于EasyExcel + 线程池解决POI文件导出时的内存溢出及超时问题
java·jvm·excel·线程池·async·虚拟机·easyexcel
Lisonseekpan37 分钟前
IntelliJ IDEA 快捷键全解析与高效使用指南
java·ide·后端·intellij-idea
liuhuapeng030438 分钟前
GetMapping自动截取List<String>字符
数据结构·windows·list
Fantasydg38 分钟前
外卖项目 day01
java
SeaTunnel39 分钟前
结项报告完整版:Apache SeaTunnel 支持 Flink 引擎 Schema Evolution 功能
java·大数据·flink·开源·seatunnel