代码随想录刷题笔记Day12-- 栈与队列之滑动窗口最大值 删除字符串中的所有相邻重复项 逆波兰表达式求值
LeetCode 239. 有效的括号
题目描述:
给你一个整数数组 nums
,有一个大小为 k
的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k
个数字。滑动窗口每次只向右移动一位。
返回 滑动窗口中的最大值 。
示例 1:
输入:nums = [1,3,-1,-3,5,3,6,7], k = 3
输出:[3,3,5,5,6,7]
解释:
滑动窗口的位置 最大值
--------------- -----
[1 3 -1] -3 5 3 6 7 3
1 [3 -1 -3] 5 3 6 7 3
1 3 [-1 -3 5] 3 6 7 5
1 3 -1 [-3 5 3] 6 7 5
1 3 -1 -3 [5 3 6] 7 6
1 3 -1 -3 5 [3 6 7] 7
解题思路
解法:
写法
var maxSlidingWindow = function(nums, k) {
let res = [];
let que = []; // 队列最多容纳k个数
for(let i = 0; i < nums.length; i++) {
if(que.length === 0) que.push(nums[i]);
else { // 维护队列
// 出队列就两种情况
// 1、 队头元素不在窗口(从队头出)
// 2、 当前元素大于队尾元素(从队尾出)
if(i - k >= 0 && nums[i - k] === que[0]) que.shift(); // 当队头元素出窗口时,弹出
// 当前元素若大于队尾元素,则移出,直到遇到小于的元素或者队列空了,进队
while(que.length > 0 && nums[i] > que[que.length - 1]){
que.pop();
}
que.push(nums[i]);
}
// 当滑动完k个元素之后开始提取队头元素
if(i >= k - 1) res.push(que[0]);
}
return res;
};
LeetCode 347. 前 K 个高频元素
题目描述:
给你一个整数数组 nums
和一个整数 k
,请你返回其中出现频率前 k
高的元素。你可以按 任意顺序 返回答案。
示例 1:
输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]
解题思路
解法:
写法
var topKFrequent = function(nums, k) {
//前k个高频元素
let hash = new Map();
//频率统计
for(let i of nums){
if(!hash.has(i)) hash.set(i,1);
else hash.set(i,hash.get(i)+1);
}
nums=new Array(hash.size);
let j=0;
for(let [key,value] of hash){
nums[j++]=[key,value];
}
getK(nums,0,nums.length-1,k);
let res=new Array(k);
for(let i=0;i<k;++i){
res[i] = nums[i][0];
}
return res;
};
//分治
var getK = function(nums,left,right,k){
if(left>=right) return ;
let temp = quikSort(nums,left,right,k);
if(temp+1==k+left) return ;
else if(temp+1<k+left){
getK(nums,temp+1,right,k-(temp+1-left)); //前面的temp+1-left已经符合要求 找剩下的k-(temp+1-left)个最大元素
} else getK(nums,left,temp-1,k); //继续找前k个最大元素
return ;
}
var quikSort = function(nums,left,right){
if(left>=right) return left;
let pivot = nums[left];
let i=left,j=right;
while(i<j){
while(nums[j][1]<pivot[1] && i<j) --j;
nums[i] = nums[j];
while(nums[i][1]>=pivot[1] && i<j) ++i;
nums[j] = nums[i];
if(i==j) nums[i] = pivot;
}
return i;
}
作者