2023.6.21
第一道困难题 辛辛苦苦写了个暴力法求解,结果测试用例来了个k=50000的窗口,直接运行超时,我真人麻了。
不管怎么样思路还是可以的,还是附上来代码:
解法一:暴力解(leetcode的实例会超时)
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
vector<int> ans;
//窗口大小 <= 数组大小 的情况
if(nums.size() <= k)
{
int max = INT_MIN;
for(int i=0; i<nums.size();i++)
{
if(nums[i] > max) max = nums[i];
}
return {max};
}
for(int i=0; i<nums.size()-k+1; i++)
{
int max = INT_MIN;
for(int j=i; j<i+k; j++)
{
if(nums[j] > max) max = nums[j];
}
ans.push_back(max);
}
return ans;
}
};
解法二:优先队列-priority_queue
优先队列指priority_queue,就是在队列的基础上增加了排序功能。内部是由堆实现的,默认是大顶堆,即最大元素排在队头。
ps:队列里的元素不用着急删除!!!用一个索引标识它就行。
思路很巧妙,直接看代码:
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
vector<int> ans;
priority_queue<pair<int,int>> queue;
for(int i=0; i<k; i++)
{
queue.emplace(nums[i],i);
}
ans.push_back(queue.top().first);
for(int i=k; i<nums.size(); i++)
{
queue.emplace(nums[i],i);
while(queue.top().second <= i-k) queue.pop();
ans.push_back(queue.top().first);
}
return ans;
}
};
优先队列好像没法用push? 得用emplace进行插入元素。
还有一种单调队列解法,改天再学把。
2023.6.22
端午快乐 把单调队列啃了一遍 需要用到deque 双端队列这个数据结构 。直接上代码:
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
vector<int> ans;
deque<int> q;
for(int i=0; i<k; i++)
{
while(!q.empty() && nums[i]>q.back()) q.pop_back();
q.push_back(nums[i]);
}
ans.push_back(q.front());
for(int i=k; i<nums.size(); i++)
{
//每次滑动都需要有一个元素出队,判断队头元素是不是这个需要出队的元素,是的话pop掉。
if(!q.empty() && q.front()==nums[i-k]) q.pop_front();
//每次push一个元素之前,会从队列尾开始把所有小于这个元素的元素pop掉,直到队列为空或者遇到一个比他大的元素
while(!q.empty() && nums[i]>q.back()) q.pop_back();
q.push_back(nums[i]);
//保存队头元素,也就是目前滑动窗口最大的元素
ans.push_back(q.front());
}
return ans;
}
};
其实整体就三个大步骤,代码中我都注释出来了。核心要点在于我们只需要维护窗口中最大的那个元素,其他元素不着急删,可以放在队列里。 思想确实难,日后再来二刷。
11.15
java三刷,代码如下:
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
int[] ans = new int[nums.length-k+1];
PriorityQueue<int[]> que = new PriorityQueue<>(new Comparator<int[]>(){
public int compare(int[] a1, int[] a2){
return a1[0] != a2[0] ? a2[0]-a1[0] : a2[1]-a1[1];
}
});
for(int i=0; i<k; i++){
que.add(new int[]{nums[i],i});
}
ans[0] = que.peek()[0];
for(int i=k; i<nums.length; i++){
que.add(new int[]{nums[i],i});
while(que.peek()[1] <= i-k) que.poll();
ans[i-k+1] = que.peek()[0];
}
return ans;
}
}