数组中的第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();
}
}

浙公网安备 33010602011771号