https://leetcode.cn/problems/the-skyline-problem/submissions/571618493/?envType=problem-list-v2&envId=XVBr8pQX
轮廓线问题
被我写的一团乱麻A过了
class MaxHeadp {
heap;
border;
compare;
constructor(nums, compare) {
this.heap = nums;
this.border = nums.length - 1;
this.compare = compare ?? ((a, b) => a - b);
this.initHeap();
}
initHeap() {
const endIndex = this.getTopNode(this.border);
for (let index = endIndex; index >= 0; index--) {
this.downNode(index);
}
}
//有多少个元素
haveNum() {
return this.border + 1;
}
//弹出最顶的
pop(index = 0) {
if (this.border === -1) {
return undefined;
}
const temp = this.heap[index];
this.heap[index] = this.heap[this.border];
this.border--;
this.downNode(index);
return temp;
}
//插入元素
insert(node) {
this.border++;
this.heap[this.border] = node;
this.upNode(this.border);
}
getNode(callback,index=0) {
if (index <= this.border) {
const result = callback(this.heap[index]);
if (result == 0) {
return { index, item: this.heap[index] };
}
const index1 = this.getNode(callback,this.getLeftNode(index));
if (index1.item !== undefined) {
return index1;
}
const index2 = this.getNode(callback,this.getRightNode(index));
if (index2.item !== undefined) {
return index2;
}
}
return { index: -1, item: undefined };
}
swap(x, y) {
let temp = this.heap[x];
this.heap[x] = this.heap[y];
this.heap[y] = temp;
}
downNode(index) {
let left = this.getLeftNode(index);
let right = this.getRightNode(index);
while (left <= this.border || right <= this.border) {
let maxIndex = undefined;
if (left <= this.border || right <= this.border) {
maxIndex =
this.compare(this.heap[left], this.heap[right]) < 0 ? right : left;
} else {
maxIndex = left <= this.border ? right : left;
}
// if (this.heap[index] < this.heap[maxIndex]) {
if (this.compare(this.heap[index], this.heap[maxIndex]) < 0) {
this.swap(index, maxIndex);
index = maxIndex;
left = this.getLeftNode(index);
right = this.getRightNode(index);
} else {
break;
}
}
}
upNode(index) {
while (index != 0) {
const parentIndex = this.getTopNode(index);
if (this.compare(this.heap[parentIndex], this.heap[index]) < 0) {
this.swap(parentIndex, index);
index = parentIndex;
} else {
break;
}
}
}
getTopNode(index) {
return Math.floor((index - 1) / 2);
}
getLeftNode(index) {
return (index + 1) * 2 - 1;
}
getRightNode(index) {
return (index + 1) * 2;
}
}
var getSkyline = function (buildings) {
const posArr = [];
for (let index = 0; index < buildings.length; index++) {
const build = buildings[index];
posArr.push({
pos: build[0],
height: build[2],
});
posArr.push({
pos: build[1],
height: -build[2],
});
}
posArr.sort((a, b) => {
if (a.pos !== b.pos) {
return a.pos - b.pos;
} else {
return b.height - a.height;
}
});
const maxHeightHeap = new MaxHeadp([], (a, b) => {
return a.height - b.height;
});
const ret = [];
for (let index = 0; index < posArr.length; index++) {
if (index === 3) {
debugger;
}
const posItem = posArr[index];
const { item: node, index: posIndex } = maxHeightHeap.getNode(
(a) => a.height - Math.abs(posItem.height)
);
if (node !== undefined) {
if (posItem.height > 0) {
node.times++;
} else {
if (node.times == 1) {
maxHeightHeap.pop(posIndex);
} else {
node.times--;
}
}
} else {
maxHeightHeap.insert({
pos: posItem.pos,
times: 1,
height: posItem.height,
});
}
const result = maxHeightHeap.heap[0];
if (maxHeightHeap.border == -1) {
if (ret[ret.length - 1][1] !== 0) {
ret.push([posItem.pos, 0]);
}
} else {
if (index == posArr.length - 1 || posArr[index + 1].pos !== posItem.pos) {
if (ret.length==0||ret[ret.length - 1][1] !== result.height) {
ret.push([posItem.pos, result.height]);
}
}
}
}
return ret;
};