数组中的第k个最大元素-leetcode

题目描述

给定整数数组 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 <= 105
  • -104 <= nums[i] <= 104

解法一

思路:

采用大根堆的方式存储数据。

java内置类实现堆:

//小根堆
PriorityQueue<Integer> minHeap = new PriorityQueue<>();


//大根堆
import java.util.PriorityQueue;
import java.util.Collections;

// 方式 A:使用 Collections 工具类
PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Collections.reverseOrder());

// 方式 B:使用 Lambda 表达式 (推荐)
PriorityQueue<Integer> maxHeap2 = new PriorityQueue<>((a, b) -> b - a);

java手动实现堆:

public class MyMaxHeap {
    private int[] heap;
    private int size;
    private int capacity;

    public MyMaxHeap(int capacity) {
        this.capacity = capacity;
        this.heap = new int[capacity];
        this.size = 0;
    }

    // 插入元素
    public void push(int val) {
        if (size == capacity) return; // 简单处理满的情况
        heap[size] = val;
        siftUp(size);
        size++;
    }

    // 弹出堆顶(最大值)
    public int pop() {
        if (size == 0) return -1;
        int root = heap[0];
        // 将最后一个元素移到堆顶,然后下滤
        heap[0] = heap[size - 1];
        size--;
        siftDown(0);
        return root;
    }

    // 上滤:将节点与父节点比较,若比父节点大则交换
    private void siftUp(int index) {
        while (index > 0) {
            int parent = (index - 1) / 2;
            if (heap[index] <= heap[parent]) break;
            swap(index, parent);
            index = parent;
        }
    }

    // 下滤:将节点与两个孩子比较,与最大的孩子交换
    private void siftDown(int index) {
        while (2 * index + 1 < size) {
            int left = 2 * index + 1;
            int right = 2 * index + 2;
            int largest = left;
            
            // 如果有右孩子且右孩子更大
            if (right < size && heap[right] > heap[left]) {
                largest = right;
            }
            
            // 如果父节点已经比孩子都大,结束
            if (heap[index] >= heap[largest]) break;
            
            swap(index, largest);
            index = largest;
        }
    }

    private void swap(int i, int j) {
        int temp = heap[i];
        heap[i] = heap[j];
        heap[j] = temp;
    }
}

代码:

class Solution {
    public int findKthLargest(int[] nums, int k) {

        //大根堆
        PriorityQueue<Integer> maxHeap2 = new PriorityQueue<>((a, b) -> b - a);
        for (int num : nums) {
            maxHeap2.add(num);
        }
        for (int i = 0; i < k-1; i++) {
            maxHeap2.poll();
        }
        return maxHeap2.peek();
    }
}
posted @ 2026-04-04 15:47  狐狸胡兔  阅读(3)  评论(0)    收藏  举报