题目描述
分析
如果在某个时间点,有多个会可以开
根据贪心,应该开的是最早结束的会议
算法
贪心,堆
过程
统计时间点对应的所有可开会议 -> 遍历所有时间点 -> 将当前时间点的所有会议放到堆中 -> 堆弹出所有不合法会议 -> 去除一个结束时间最早的会议并递增结果
统计
用一个数组,统计所有的时间点(最大为 Math.pow(10, 5)) 可以开的所有会议
遍历时间
从 1 开始,一直遍历到最大时间 MAX,首先在堆中放入当前时间下所有可开的会议
我们要做的是,在这个时间点,优先开最早结束的会议,因为这样可以达到最优结果,即开最多的会
统计结果
先弹出所有不合法的会议,即开会时间没发满足当前时间点的
然后弹出一个在这个时间点要去开的会议,递增统计结果
代码
/**
* @param {number[][]} events
* @return {number}
*/
var maxEvents = function (events) {
const n = events.length,
max = Math.pow(10, 5),
left = new Array(max + 1).fill(0).map(() => new Array()),
h = new Heap((a, b) => {
if (b === undefined) return false
return a[1] > b[1]
})
let ans = 0
for (let i = 0; i < n; i++) {
const e = events[i]
left[e[0]].push(e)
}
for (let i = 1; i <= max; i++) {
for (const x of left[i]) {
if (x[0] <= i) h.insert(x)
}
while (!h.isEmpty() && h.top()[1] < i) h.extract()
if (!h.isEmpty()) {
h.extract()
ans++
}
}
return ans
}
class Heap {
constructor(compareFn) {
this.compareFn = compareFn
this.heap = []
}
getLeftIndex(index) {
return index * 2 + 1
}
getRightIndex(index) {
return index * 2 + 2
}
getParentIndex(index) {
return Math.floor((index - 1) / 2)
}
size() {
return this.heap.length
}
isEmpty() {
return this.size() === 0
}
swap(parent, index) {
const arr = this.heap;
;[arr[parent], arr[index]] = [arr[index], arr[parent]]
}
insert(value) {
const index = this.heap.length
this.heap.push(value)
this.siftUp(index)
}
siftUp(index) {
let parent = this.getParentIndex(index)
while (
index > 0 &&
this.compareFn(this.heap[parent], this.heap[index])
) {
this.swap(parent, index)
index = parent
parent = this.getParentIndex(index)
}
}
extract() {
if (this.isEmpty()) return
if (this.size() === 1) return this.heap.pop()
const removedItem = this.heap[0]
this.heap[0] = this.heap.pop()
this.siftDown(0)
return removedItem
}
siftDown(index) {
let element = index
const left = this.getLeftIndex(index)
const right = this.getRightIndex(index)
if (
index < this.size() &&
this.compareFn(this.heap[element], this.heap[left])
) {
element = left
}
if (
index < this.size() &&
this.compareFn(this.heap[element], this.heap[right])
) {
element = right
}
if (element !== index) {
this.swap(element, index)
this.siftDown(element)
}
}
top() {
return this.heap[0]
}
}