数组算法之【数组中第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];
        }
    }
}
相关推荐
wearegogog1234 小时前
基于 MATLAB 的卡尔曼滤波器实现,用于消除噪声并估算信号
前端·算法·matlab
韩师学子--小倪4 小时前
fastjson与gson的toString差异
java·json
一只小小汤圆4 小时前
几何算法库
算法
Drawing stars4 小时前
JAVA后端 前端 大模型应用 学习路线
java·前端·学习
Evand J4 小时前
【2026课题推荐】DOA定位——MUSIC算法进行多传感器协同目标定位。附MATLAB例程运行结果
开发语言·算法·matlab
nbsaas-boot4 小时前
SQL Server 存储过程开发规范(公司内部模板)
java·服务器·数据库
行百里er5 小时前
用 ThreadLocal + Deque 打造一个“线程专属的调用栈” —— Spring Insight 的上下文管理术
java·后端·架构
leo__5205 小时前
基于MATLAB的交互式多模型跟踪算法(IMM)实现
人工智能·算法·matlab
忆锦紫5 小时前
图像增强算法:Gamma映射算法及MATLAB实现
开发语言·算法·matlab
玄〤5 小时前
黑马点评中 VoucherOrderServiceImpl 实现类中的一人一单实现解析(单机部署)
java·数据库·redis·笔记·后端·mybatis·springboot