Furthest Building You Can Reach
MediumArrayGreedyHeap (Priority Queue)
Solution
export function furthestBuilding(heights: number[], bricks: number, ladders: number): number {
const heap = new Heap();
for (let currentIndex = 0; currentIndex < heights.length - 1; currentIndex++) {
const heightDiff = heights[currentIndex + 1] - heights[currentIndex];
if (0 < heightDiff) {
heap.push(heightDiff);
}
if (ladders < heap.length) {
bricks -= heap.pop() || 0;
}
if (bricks < 0) {
return currentIndex;
}
}
return heights.length - 1;
}
class Heap {
heap: number[];
constructor() {
this.heap = [];
}
get length() {
return this.heap.length;
}
get peek(): number | undefined {
return this.heap[0];
}
private swap(index1: number, index2: number): void {
[this.heap[index1], this.heap[index2]] = [this.heap[index2], this.heap[index1]];
}
private parentIndex(index: number): number {
return (index - 1) >> 1;
}
private leftIndex(index: number): number {
return (index << 1) + 1;
}
private rightIndex(index: number): number {
return (index << 1) + 2;
}
private shiftDown(): void {
let currentIndex = 0;
while (this.leftIndex(currentIndex) < this.length) {
const leftIndex = this.leftIndex(currentIndex);
const rightIndex = this.rightIndex(currentIndex);
const childIndex =
rightIndex < this.length && this.heap[rightIndex] < this.heap[leftIndex]
? rightIndex
: leftIndex;
if (this.heap[currentIndex] <= this.heap[childIndex]) {
return;
}
this.swap(currentIndex, childIndex);
currentIndex = childIndex;
}
}
private shiftUp(): void {
let currentIndex = this.length - 1;
while (0 < currentIndex) {
const parentIndex = this.parentIndex(currentIndex);
if (this.heap[parentIndex] <= this.heap[currentIndex]) {
return;
}
this.swap(currentIndex, parentIndex);
currentIndex = parentIndex;
}
}
push(item: number): void {
this.heap.push(item);
this.shiftUp();
}
pop(): number | undefined {
if (this.length <= 1) {
return this.heap.pop();
}
const result = this.peek;
this.swap(0, this.length - 1);
this.heap.pop();
this.shiftDown();
return result;
}
}
/* DFS(Time Limit Exceeded)
function furthestBuilding(
heights: number[],
bricks: number,
ladders: number
): number {
function dfs(
currentIndex: number,
currentBricks: number,
currentLadders: number
): number {
if (currentBricks < 0 || currentLadders < 0) {
return -1;
}
if (currentIndex === heights.length - 1) {
return currentIndex;
}
const heightDiff = heights[currentIndex + 1] - heights[currentIndex];
if (heightDiff <= 0) {
return dfs(currentIndex + 1, currentBricks, currentLadders);
}
return Math.max(
currentIndex,
dfs(currentIndex + 1, currentBricks - heightDiff, currentLadders),
dfs(currentIndex + 1, currentBricks, currentLadders - 1)
);
}
return dfs(0, bricks, ladders);
}
*/