题意
书的编号,从0开始,某人借书,传入2个参数:start和end,表示从编号为start的书开始借,借到编号为end - 1的书为止,执行完book工作后,函数返回书里面,被借次数最多的次数。
思路
这道题的解题思路不是我自己想的,是在看完答案后领悟的。
最简单的思路肯定是拉个数组,每次有人book,就把从start到end-1的编号的值加一喽,但是这样肯定会超时。
简单的方法是在每次book的start跟end加个值就好了,假设有个游标,从0开始向右滑,滑到start的时候,它的值会加上start上面的count值,滑到end的时候,他的值会加上end上面的为负数的count值。
用个数组存储这里的start跟end的点,循环遍历,同时自增游标的值,比对跟max的大小,如果大于max,max重新赋值。
问题是用Array的话,比如Array[5]为undefined,Array[5]在循环里还是会被循环到,浪费了运行时间,事实是,我就这么提交了,然后还是被Time Exeeded了。。。
解决方案是用Map存储这个尺,在最后要count的时候,利用Array.from 把Map转换为数组,然后再用js自带的sort(这个效率高点),再把游标从小到大遍历,记录max。即可。
贴代码
var MyCalendarThree = function() {
this.list = new Map();
};
/**
* @param {number} start
* @param {number} end
* @return {number}
*/
MyCalendarThree.prototype.book = function(start, end) {
let tmp = this.list.get(start);
tmp = tmp === undefined ? 1 : ++tmp;
this.list.set(start, tmp);
tmp = this.list.get(end);
tmp = tmp === undefined ? -1 : --tmp;
this.list.set(end, tmp);
let tmpList = Array.from(this.list);
tmpList.sort((a, b) => a[0] - b[0]);
let max = 0, val = 0;
for(let i = 0; i < tmpList.length; ++i){
let tmp = tmpList[i][1];
if(tmp !== undefined){
val += tmp;
max = Math.max(max, val);
}
}
return max;
};