概念
堆是一种特殊的完全二叉树
所有节点都大于等于(最大堆)或小于等于(最小堆)它的子节点
Js中通常用数组表示堆,左侧子节点的位置是2*index+1,右侧子节点的位置是2*index+2
父节点的位置是(index-1)/2
JS类构建最小堆
class minHeap {
constructor(){
this.heap=[];
}
swap(i1,i2){
let temp=this.heap[i1];
this.heap[i1]=this.heap[i2];
this.heap[i2]=temp;
}
getParentIndex(i){
return (i-1)/2
}
getLeftIndex(i){
return i*2+1
}
getRightIndex(i){
return i*2+2
}
shiftUp(index){
if(index==0){return}
let parentIndex=getParentIndex(index);
if(this.heap[index]<this.heap[parentIndex]){
this.swap(index,parentIndex);
this.shiftUp(parentIndex);
}}
shiftDown(index){
let leftIndex=this.getLeftIndex(index);
let rightIndex=this.getRightIndex(index);
if(this.heap[leftIndex]<this.heap[index]){
this.swap(index,leftIndex);
this.shiftDown(leftIndex);
}
if(this.heap[rightIndex]<this.heap[index]){
this.swap(index,rightIndex);
this.shiftDown(rightIndex);
}
}
insertValue(value){
this.heap.push(value);
this.shiftUp(this.heap.length-1);
}
pop(value){
this.heap[0]=this.heap.pop();
shiftDown(0);
}
peak(){
return this.heap[0];
}
size(){
return this.heap.length
}
}
const h=new minHeap();
h.insertValue(2);
h.insertValue(1);
h.insertValue(6);
h.insertValue(5);
h.insertValue(4);
h.insertValue(3);
h.pop();
h.peak();
h.size();
console.log(h.heap);
最小堆求解数组中最大的第k个元素
class minHeap {
constructor(){
this.heap=[];
}
swap(i1,i2){
let temp=this.heap[i1];
this.heap[i1]=this.heap[i2];
this.heap[i2]=temp;
}
getParentIndex(i){
return Math.floor((i-1)/2)
}
getLeftIndex(i){
return i*2+1
}
getRightIndex(i){
return i*2+2
}
shiftUp(index){
if(index==0){return}
let parentIndex=this.getParentIndex(index);
if(this.heap[index]<this.heap[parentIndex]){
this.swap(index,parentIndex);
this.shiftUp(parentIndex);
}}
shiftDown(index){
let leftIndex=this.getLeftIndex(index);
let rightIndex=this.getRightIndex(index);
if(this.heap[leftIndex]<this.heap[index]){
this.swap(index,leftIndex);
this.shiftDown(leftIndex);
}
if(this.heap[rightIndex]<this.heap[index]){
this.swap(index,rightIndex);
this.shiftDown(rightIndex);
}
}
insertValue(value){
this.heap.push(value);
this.shiftUp(this.heap.length-1);
}
pop(value){
this.heap[0]=this.heap.pop();
this.shiftDown(0);
}
peak(){
return this.heap[0];
}
size(){
return this.heap.length
}
}
var findKthLargest = function(nums, k) {
const h=new minHeap();
nums.forEach(n=>{
h.insertValue(n);
if(h.size()>k){
h.pop();
} });
return h.peak()
};
前k个高频元素
var topKFrequent = function(nums, k) {
let map=new Map();
nums.forEach(n=>{
map.set(n,map.has(n)? map.get(n)+1:1)
});
let arr=Array.from(map).sort((a,b)=> b[1]-a[1]);
return arr.slice(0,k).map(n=>n[0])
};
合并K个排序链表
class minHeap {
constructor(){
this.heap=[];
}
swap(i1,i2){
let temp=this.heap[i1];
this.heap[i1]=this.heap[i2];
this.heap[i2]=temp;
}
getParentIndex(i){
return Math.floor((i-1)/2)
}
getLeftIndex(i){
return i*2+1
}
getRightIndex(i){
return i*2+2
}
shiftUp(index){
if(index==0){return}
let parentIndex=this.getParentIndex(index);
if(this.heap[parentIndex]&&this.heap[index].val<this.heap[parentIndex].val){
this.swap(index,parentIndex);
this.shiftUp(parentIndex);
}}
shiftDown(index){
let leftIndex=this.getLeftIndex(index);
let rightIndex=this.getRightIndex(index);
if(this.heap[leftIndex]&&this.heap[leftIndex].val<this.heap[index].val){
this.swap(index,leftIndex);
this.shiftDown(leftIndex);
}
if(this.heap[rightIndex]&&this.heap[rightIndex].val<this.heap[index].val){
this.swap(index,rightIndex);
this.shiftDown(rightIndex);
}
}
insertValue(value){
this.heap.push(value);
this.shiftUp(this.heap.length-1);
}
pop(value){
if(this.size()===1)return this.heap.shift()
const top =this.heap[0];
this.heap[0]=this.heap.pop();
this.shiftDown(0);
return top
}
peak(){
return this.heap[0];
}
size(){
return this.heap.length
}
}
var mergeKLists = function(lists) {
let list=new ListNode(0);
let p=list;
let h=new minHeap();
lists.forEach(n=>{if(n)h.insertValue(n)});
while(h.size()){
let n=h.pop();
p.next=n;
p=p.next;
if(n.next){h.insertValue(n.next);}
}
return list.next
};