数组算法之【数组中第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];
        }
    }
}
相关推荐
Morriser莫18 分钟前
图论Day2学习心得
算法·图论
zyd091525 分钟前
代码随想录Day50:图论(图论理论、深度搜索理论、所有可达路径、广度搜索理论)
java·数据结构·算法·leetcode·图论
Cl_rown去掉l变成C28 分钟前
第R5周:天气预测
人工智能·python·深度学习·算法·tensorflow2
都叫我大帅哥40 分钟前
Flink Slot 终极指南:从入门到避坑,幽默解析分布式计算的“工位经济学
java·大数据·flink
小凡敲代码41 分钟前
2025年最新Java后端场景面试题(大厂真题+解析)
java·程序员·java面试·java面试题·后端开发·java场景题·2025求职面试
CoovallyAIHub1 小时前
VisDrone数据集,专为无人机视觉任务打造
深度学习·算法·计算机视觉
摇滚侠1 小时前
面试实战 问题三十二 Java中创建对象的几种方式
java·面试·职场和发展
啊阿狸不会拉杆1 小时前
《算法导论》第 22 章 - 基本的图算法
c++·算法·排序算法·图论·拓扑学
BestAns1 小时前
Java中如何判断两个值是否相等?一篇文章讲透比较机制
java
freed_Day1 小时前
Java进阶学习之Stream流的基本概念以及使用技巧
java·开发语言·学习