目录
703. 数据流中的第 K 大元素
思路
题目解析:
数据流:
数据流和数组的区别:
代码实现
小顶堆类
测试类
力扣
我想成为一个强大、坦荡又热血的人,我爱霓虹闪烁,也爱高山流水,更爱我自己
—— 24.10.13
703. 数据流中的第 K 大元素
设计一个找到数据流中第
k
大元素的类(class)。注意是排序后的第k
大元素,不是第k
个不同的元素。请实现
KthLargest
类:
KthLargest(int k, int[] nums)
使用整数k
和整数流nums
初始化对象。int add(int val)
将val
插入数据流nums
后,返回当前数据流中第k
大的元素。示例 1:
输入:
["KthLargest", "add", "add", "add", "add", "add"]
[[3, [4, 5, 8, 2]], [3], [5], [10], [9], [4]]输出:[null, 4, 5, 5, 8, 8]
解释:
KthLargest kthLargest = new KthLargest(3, [4, 5, 8, 2]);
kthLargest.add(3); // 返回 4
kthLargest.add(5); // 返回 5
kthLargest.add(10); // 返回 5
kthLargest.add(9); // 返回 8
kthLargest.add(4); // 返回 8示例 2:
输入:
["KthLargest", "add", "add", "add", "add"]
[[4, [7, 7, 7, 7, 8, 3]], [2], [10], [9], [9]]输出:[null, 7, 7, 7, 8]
解释:
KthLargest kthLargest = new KthLargest(4, [7, 7, 7, 7, 8, 3]);
kthLargest.add(2); // 返回 7
kthLargest.add(10); // 返回 7
kthLargest.add(9); // 返回 7
kthLargest.add(9); // 返回 8
思路
题目解析:
题目要求实现KthLargest类,参数列表要求传入一个整数k,代表要查找的由高到低的顺序排列,add方法,要求传入一个整数,将这个整数加入到原先数组中,按照顺序排列,当数据流有新的元素的时候,重新按升序排序数组,倒数第k个元素就是第k大的数,再从加入元素后并已排序的数组中找到倒数第k个元素,将倒数第k个元素返回
数据流:
在编程中,数据流指的是一系列连续的数据元素在系统中流动和处理的概念,本题中的数据流由整型数组实现
数据流和数组的区别:
数据流的数据是变化的,意味着有可能有更多的元素添加进来,数组是固定的
代码实现
小顶堆类
import java.util.Arrays;
public class MinHeap {
int[] heapArray;
int size;
public MinHeap(int capacity) {
heapArray = new int[capacity];
}
public MinHeap(int[] Array) {
heapArray = new int[Array.length];
System.arraycopy(Array, 0, heapArray, 0, Array.length);
size = Array.length;
buildHeap();
}
private void buildHeap() {
for (int i = size / 2 - 1; i >= 0; i--) {
heapifyDown(i);
}
}
public void heapifyDown(int index) {
int leftChildIndex = 2 * index + 1;
int rightChildIndex = leftChildIndex + 1;
int SmallIndex = index;
if (leftChildIndex < size && heapArray[leftChildIndex] < heapArray[SmallIndex]) {
SmallIndex = leftChildIndex;
}
if (rightChildIndex < size && heapArray[rightChildIndex] < heapArray[SmallIndex]) {
SmallIndex = rightChildIndex;
}
if (SmallIndex!= index) {
swap(index, SmallIndex);
heapifyDown(SmallIndex);
}
}
public void swap(int i, int j) {
int temp = heapArray[i];
heapArray[i] = heapArray[j];
heapArray[j] = temp;
}
public int peek() {
if (size == 0) {
return -1;
}
return heapArray[0];
}
public int poll() {
if (size == 0) {
return -1;
}
int maxValue = heapArray[0];
heapArray[0] = heapArray[size - 1];
size--;
heapifyDown(0);
return maxValue;
}
public int poll(int index) {
if (size == 0 || index >= size) {
return -1;
}
int removedValue = heapArray[index];
heapArray[index] = heapArray[size - 1];
size--;
heapifyDown(index);
return removedValue;
}
public void replace(int newValue) {
if (size == 0) {
return;
}
heapArray[0] = newValue;
heapifyDown(0);
}
public boolean offer(int value) {
if (size == heapArray.length) {
return false;
}
heapArray[size] = value;
heapifyUp(size);
size++;
return true;
}
private void heapifyUp(int index) {
int parentIndex = (index - 1) / 2;
while (index > 0 && heapArray[index] < heapArray[parentIndex]) {
swap(index, parentIndex);
index = parentIndex;
parentIndex = (index - 1) / 2;
}
}
public boolean isFull(){
return size == heapArray.length;
}
public static void main(String[] args) {
int[] Arr = {1, 2, 3, 4, 5, 6, 7};
MinHeap maxHeap = new MinHeap(Arr);
System.out.println(Arrays.toString(maxHeap.heapArray));
// [7, 5, 6, 4, 2, 1, 3]
maxHeap.replace(5);
System.out.println(Arrays.toString(maxHeap.heapArray));
// [6, 5, 5, 4, 2, 1, 3]
maxHeap.poll(2);
System.out.println(Arrays.toString(maxHeap.heapArray));
// [6, 5, 3, 4, 2, 1, 3]
System.out.println(maxHeap.peek());
// 6
maxHeap.poll();
System.out.println(Arrays.toString(maxHeap.heapArray));
// [5, 4, 3, 1, 2, 1, 3]
System.out.println(maxHeap.offer(5));
// true
System.out.println(Arrays.toString(maxHeap.heapArray));
// [5, 4, 5, 1, 2, 3, 3]
maxHeap.poll();
System.out.println(Arrays.toString(maxHeap.heapArray));
// [5, 4, 3, 1, 2, 3, 3]
maxHeap.offer(9);
System.out.println(Arrays.toString(maxHeap.heapArray));
// [9, 4, 5, 1, 2, 3, 3]
}
}
测试类
public class LeetCode703MaxInDataStream {
private MinHeap heap;
// 在数组之中寻找第k大的元素
public LeetCode703MaxInDataStream(int k,int[] nums) {
heap = new MinHeap(k);
for (int num : nums) {
add(num);
}
}
// 不断调用,模拟数据流中新传来的元素
public int add(int val){
if (!heap.isFull()){
heap.offer(val);
}else if(val > heap.peek()){
heap.replace(val);
}
return heap.peek();
}
public static void main(String[] args) {
LeetCode703MaxInDataStream test = new LeetCode703MaxInDataStream(3,new int[]{5,7,9,6,4});
// 小顶堆,4 5 8 留下最大的k个就行
System.out.println(test.add(11));
System.out.println(test.add(7));
System.out.println(test.add(9));
System.out.println(test.add(6));
System.out.println(test.add(4));
}
}
力扣
import java.util.Arrays;
public class MinHeap {
int[] heapArray;
int size;
public MinHeap(int capacity) {
heapArray = new int[capacity];
}
public MinHeap(int[] Array) {
heapArray = new int[Array.length];
System.arraycopy(Array, 0, heapArray, 0, Array.length);
size = Array.length;
buildHeap();
}
private void buildHeap() {
for (int i = size / 2 - 1; i >= 0; i--) {
heapifyDown(i);
}
}
public void heapifyDown(int index) {
int leftChildIndex = 2 * index + 1;
int rightChildIndex = leftChildIndex + 1;
int SmallIndex = index;
if (leftChildIndex < size && heapArray[leftChildIndex] < heapArray[SmallIndex]) {
SmallIndex = leftChildIndex;
}
if (rightChildIndex < size && heapArray[rightChildIndex] < heapArray[SmallIndex]) {
SmallIndex = rightChildIndex;
}
if (SmallIndex!= index) {
swap(index, SmallIndex);
heapifyDown(SmallIndex);
}
}
public void swap(int i, int j) {
int temp = heapArray[i];
heapArray[i] = heapArray[j];
heapArray[j] = temp;
}
public int peek() {
if (size == 0) {
return -1;
}
return heapArray[0];
}
public int poll() {
if (size == 0) {
return -1;
}
int maxValue = heapArray[0];
heapArray[0] = heapArray[size - 1];
size--;
heapifyDown(0);
return maxValue;
}
public int poll(int index) {
if (size == 0 || index >= size) {
return -1;
}
int removedValue = heapArray[index];
heapArray[index] = heapArray[size - 1];
size--;
heapifyDown(index);
return removedValue;
}
public void replace(int newValue) {
if (size == 0) {
return;
}
heapArray[0] = newValue;
heapifyDown(0);
}
public boolean offer(int value) {
if (size == heapArray.length) {
return false;
}
heapArray[size] = value;
heapifyUp(size);
size++;
return true;
}
private void heapifyUp(int index) {
int parentIndex = (index - 1) / 2;
while (index > 0 && heapArray[index] < heapArray[parentIndex]) {
swap(index, parentIndex);
index = parentIndex;
parentIndex = (index - 1) / 2;
}
}
public boolean isFull(){
return size == heapArray.length;
}
public static void main(String[] args) {
int[] Arr = {1, 2, 3, 4, 5, 6, 7};
MinHeap maxHeap = new MinHeap(Arr);
System.out.println(Arrays.toString(maxHeap.heapArray));
// [7, 5, 6, 4, 2, 1, 3]
maxHeap.replace(5);
System.out.println(Arrays.toString(maxHeap.heapArray));
// [6, 5, 5, 4, 2, 1, 3]
maxHeap.poll(2);
System.out.println(Arrays.toString(maxHeap.heapArray));
// [6, 5, 3, 4, 2, 1, 3]
System.out.println(maxHeap.peek());
// 6
maxHeap.poll();
System.out.println(Arrays.toString(maxHeap.heapArray));
// [5, 4, 3, 1, 2, 1, 3]
System.out.println(maxHeap.offer(5));
// true
System.out.println(Arrays.toString(maxHeap.heapArray));
// [5, 4, 5, 1, 2, 3, 3]
maxHeap.poll();
System.out.println(Arrays.toString(maxHeap.heapArray));
// [5, 4, 3, 1, 2, 3, 3]
maxHeap.offer(9);
System.out.println(Arrays.toString(maxHeap.heapArray));
// [9, 4, 5, 1, 2, 3, 3]
}
}
class KthLargest {
private MinHeap heap;
// 在数组之中寻找第k大的元素
public KthLargest(int k,int[] nums) {
heap = new MinHeap(k);
for (int num : nums) {
add(num);
}
}
// 不断调用,模拟数据流中新传来的元素
public int add(int val){
if (!heap.isFull()){
heap.offer(val);
}else if(val > heap.peek()){
heap.replace(val);
}
return heap.peek();
}
}
/**
* Your KthLargest object will be instantiated and called as such:
* KthLargest obj = new KthLargest(k, nums);
* int param_1 = obj.add(val);
*/