1. 队列的最大值
请定义一个队列并实现函数 max_value 得到队列里的最大值,要求函数max_value、push_back 和 pop_front 的均摊时间复杂度都是O(1)。
若队列为空,pop_front 和 max_value 需要返回 -1。
我最开始想的很简单,循环遍历最大值就可以了。删除数组头部元素和添加数组尾部元素,js数组都有原生方法,但是注意题目要求均摊时间复杂度为-1。所以我参考了题解,通过两个队列实现了该目标,唯一遗憾的是js的shift()方法时间复杂度为O(n),所以我使用splice()方法代替了。
var MaxQueue = function() {
this.array = [];
this.maxArray = [];
};
/**
* @return {number}
*/
MaxQueue.prototype.max_value = function() {
if(this.array.length === 0){
return -1;
}
return this.maxArray[0];
};
/**
* @param {number} value
* @return {void}
*/
MaxQueue.prototype.push_back = function(value) {
while(this.maxArray.length > 0 && this.maxArray[this.maxArray.length- 1] < value){
this.maxArray.pop();
}
this.array[this.array.length] = value;
this.maxArray.push(value);
};
/**
* @return {number}
*/
MaxQueue.prototype.pop_front = function() {
if(this.array.length === 0){
return -1;
}
let value = this.array.splice(0, 1)[0];
if(value === this.maxArray[0]){
this.maxArray.splice(0, 1);
}
return value;
};
/**
* Your MaxQueue object will be instantiated and called as such:
* var obj = new MaxQueue()
* var param_1 = obj.max_value()
* obj.push_back(value)
* var param_3 = obj.pop_front()
*/
2. 滑动窗口的最大值
给定一个数组 nums 和滑动窗口的大小 k,请找出所有滑动窗口里的最大值。
我想的很简单,用一个数组保存窗口内的值,在循环改变数组,求改变后的最大值即可。 这是比较简单实现,而且比较容易理解的思路,所以我的排名在前百分之五十。 而推荐题解的思路是,新建一个单调队列,求出最大值后,在窗口移动时比较移除的数是不是最大值,如果是,那就出单调队列。这样就保证的处于单调队列前的数肯定为窗口的最大值。
/**
* @param {number[]} nums
* @param {number} k
* @return {number[]}
*/
var maxSlidingWindow = function (nums, k) {
if (nums.length === 0 || nums.length === 1 || k === 1) {
return nums;
}
let maxValueArray = [nums.length - k + 1];
let maxValue = null;
let subArray = nums.slice(0, k);
for (let i = 0; i < nums.length - k + 1; ++i) {
if (maxValue && subArray[k] > maxValue) {
maxValue = subArray[k];
} else {
let index = 0;
while (index < k) {
let value = subArray[index];
if (maxValue !== null) {
maxValue = maxValue > value ? maxValue : value;
} else {
maxValue = value;
}
++index;
}
}
maxValueArray[i] = maxValue;
if (nums[i] == maxValue) {
maxValue = null;
}
subArray.shift();
subArray.push(nums[i + k]);
}
return maxValueArray;
// 推荐题解
// if(nums.length === 0 || nums.length === 1 || k === 1){
// return nums;
// }
// let array = [];
// let windows = [];
// for (let i = 0; i < nums.length; ++i) {
// if (i >= k + windows[0]) {
// windows.shift();
// }
// while (windows.length > 0 && nums[i] > nums[windows[windows.length - 1]]) {
// windows.pop();
// }
// windows.push(i);
// if (i >= k - 1) {
// array.push(nums[windows[0]]);
// }
// }
return array;
};