js(62)~ [703] 数据流中的第 K 大元素(迷糊)

89 阅读1分钟

这个题目前理解不了啊,什么最小栈到时能理解,但是操作最小栈,理解不了了,吵了一个代码比较简单的,但是up和down函数理解不了啊

class MinHeap {
	constructor(k, nums) {
		this.heap = [];
		this.k = k;
	}
	add(num) {
		// 当 heap 数组长度不够 k 时,新数从数组末尾推入,执行“上浮”,交换到它合适的位置。
		if (this.heap.length < this.k) {
			this.heap.push(num);
			this.up(this.heap.length - 1)
			//当 heap 数组长度够 k 时,如果新数字比栈顶大,用它替换堆顶,执行“下沉”,交换到合适的位置。
		} else if (num > this.heap[0]) {
			this.heap[0] = num;
			this.down(0)
		}
	}
        // 将索引i上的元素,上浮到合适位置
	up(i) {
		while (i > 0) {
                // 找到父节点在heap数组中的位置
			const parent = (i - 1) >> 1;
                        // 如果父节点比插入的数字大
			if (this.heap[parent] > this.heap[i]) {
				[this.heap[parent], this.heap[i]] = [this.heap[i], this.heap[parent]]; // 交换
				i = parent; // 更新
                                 // 父比自己小,满足最小堆的性质,break
			} else {
				break;
			}
		}
	}

    // 下沉到合适的位置
	down(i) {
        // 左子节点索引如果已经越界,终止下沉
		while (2 * i + 1 < this.heap.length) {
			let child = 2 * i + 1; // 左子节点在heap数组中的位置
                        // 如果右子节点存在 并且 更小 就用它去比较
			if (child + 1 < this.heap.length && this.heap[child + 1] < this.heap[child]) {
				child++;
			}
                        // 如果插入的数字比子节点都大
			if (this.heap[i] > this.heap[child]) {
				[this.heap[child], this.heap[i]] = [this.heap[i], this.heap[child]];
				i = child;
                                // 子比自己大,满足最小堆的属性,break
			} else {
				break;
			}
		}
	}
}
var KthLargest = function (k, nums) {
	this.heap = new MinHeap(k, nums);
	for (const item of nums) {
		this.heap.add(item);
	}

};

/** 
 * @param {number} val
 * @return {number}
 */
KthLargest.prototype.add = function (val) {
	this.heap.add(val);
	return this.heap.heap[0];
};