239 滑动窗口最大值
题目链接/文章讲解/视频讲解:https://programmercarl.com/0239.%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3%E6%9C%80%E5%A4%A7%E5%80%BC.html
方法一:自己写的,但是执行很长的测试用例会超时,一开始我写的是while循环,有点没搞懂,后来在何包蛋的帮助下改成了for循环就对了。
var maxSlidingWindow = function(nums, k) {
let res = [];
//这里i的范围需要-k,因为i走不到最后一个
for(let i = 0;i<=nums.length - k;i++){
let j = i+k-1;
let p = i;
// while(p<=j){
// let max = nums[p];
// let temp = nums[++p];
// if(temp > max){
// max = temp;
// }
let max = nums[i];
for(let p = i+1;p<=j;p++){
if(nums[p] > max){
max = nums[p];
}
}
res.push(max);
// console.log(res);
// }
}
return res;
}
时间复杂度O(n*k)
方法二:单调队列:单调递减的双端队列
注意,往单调队列里push进去的是索引,而不是元素
/**
* @param {number[]} nums
* @param {number} k
* @return {number[]}
*/
var maxSlidingWindow = function (nums, k) {
const q = [];//单递减的双端队列
const ans = [];//最后的返回结果
for (let i = 0; i < nums.length; i++) {//循环nums
//当进入滑动窗口的元素大于等于队尾的元素时 不断从队尾出队,
//直到进入滑动窗口的元素小于队尾的元素,以保证单调递减的性质
while (q.length && nums[i] >= nums[q[q.length - 1]]) {
q.pop();
}
q.push(i);//元素的索引入队
while (q[0] <= i - k) {//队头元素已经在滑动窗口外了,移除队头元素
q.shift();
}
//当i大于等于k-1的时候,单调递减队头就是滑动窗口的最大值
if (i >= k - 1) ans.push(nums[q[0]]);
}
return ans;
};
参考题解:
347 前k个高频元素
题目链接/文章讲解/视频讲解:https://programmercarl.com/0347.%E5%89%8DK%E4%B8%AA%E9%AB%98%E9%A2%91%E5%85%83%E7%B4%A0.html
方法一:哈希表
哈希表是无序的,因此必须转成数组,再截取前k个。
/**
* @param {number[]} nums
* @param {number} k
* @return {number[]}
*/
var topKFrequent = function(nums, k) {
const map = new Map();
for(let i=0;i<nums.length;i++){
if(map.has(nums[i])){
map.set(nums[i],map.get(nums[i])+1);
}else{
map.set(nums[i],1);
}
}
//nums.forEach(n => {
// map.set(n, map.has(n) ? map.get(n)+1 : 1)
//})
// 首先将字典转成数组,然后对数组中的第二个元素(频度)从大到小排序
//按照value进行排序
const list = Array.from(map).sort((a, b) => b[1] - a[1])
//console.log(map); Map(3) { 1 => 3, 2 => 2, 3 => 1 }
//console.log(list); [ [ 1, 3 ], [ 2, 2 ], [ 3, 1 ] ]
// 截取频率前k高的元素
//console.log(list.slice(0, k)); [ [ 1, 3 ], [ 2, 2 ] ]
return list.slice(0, k).map(n => n[0]);
//return list.slice(0, k).map(function(n){
// return n[0];
//})
};
JS数组高阶函数map的用法:https://blog.csdn.net/dyk11111/article/details/131247932
方法二:大根堆(待补充)