《剑指Offer——滑动窗口的最大值,队列的最大值》代码
Posted 穿迷彩服的鲨鱼
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《剑指Offer——滑动窗口的最大值,队列的最大值》代码相关的知识,希望对你有一定的参考价值。
滑动窗口的最大值,队列的最大值
前言
//==================================================================
// 《剑指Offer——滑动窗口的最大值,队列的最大值》代码
//==================================================================
// 题目:给定一个数组和滑动窗口的大小,请找出所有滑动窗口里的最大值。例如,
// 如果输入数组{2, 3, 4, 2, 6, 2, 5, 1}及滑动窗口的大小3,那么一共存在6个
// 滑动窗口,它们的最大值分别为{4, 4, 6, 6, 6, 5},
// =================================================================
// 题目:给定一个数组和滑动窗口的大小,请找出所有滑动窗口里的最大值。例如,
// 如果输入数组{2, 3, 4, 2, 6, 2, 5, 1}及滑动窗口的大小3,那么一共存在6个
// 滑动窗口,它们的最大值分别为{4, 4, 6, 6, 6, 5},
//==================================================================
一、示例
1.滑动窗口的最大值
/*=====================================================================
剑指 Offer 59 - I. 滑动窗口的最大值
给定一个数组 nums 和滑动窗口的大小 k,请找出所有滑动窗口里的最大值。
示例:
输入: 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
=====================================================================*/
2.队列的最大值
/*====================================================================
剑指 Offer 59 - II. 队列的最大值
请定义一个队列并实现函数 max_value 得到队列里的最大值,
要求函数max_value、push_back 和 pop_front 的均摊时间复杂度都是O(1)。
若队列为空,pop_front 和 max_value 需要返回 -1
示例 1:
输入:
["MaxQueue","push_back","push_back","max_value","pop_front","max_value"]
[[],[1],[2],[],[],[]]
输出: [null,null,null,2,1,2]
示例 2:
输入:
["MaxQueue","pop_front","max_value"]
[[],[],[]]
====================================================================*/
二、代码解析
1.新建.cpp文件
代码如下(示例):
//==================================================================
// 《剑指Offer——滑动窗口的最大值,队列的最大值》代码
//==================================================================
// 题目:给定一个数组和滑动窗口的大小,请找出所有滑动窗口里的最大值。例如,
// 如果输入数组{2, 3, 4, 2, 6, 2, 5, 1}及滑动窗口的大小3,那么一共存在6个
// 滑动窗口,它们的最大值分别为{4, 4, 6, 6, 6, 5},
// =================================================================
// 题目:给定一个数组和滑动窗口的大小,请找出所有滑动窗口里的最大值。例如,
// 如果输入数组{2, 3, 4, 2, 6, 2, 5, 1}及滑动窗口的大小3,那么一共存在6个
// 滑动窗口,它们的最大值分别为{4, 4, 6, 6, 6, 5},
//==================================================================
#include <iostream>
#include<vector>
#include<deque>
#include<queue>
using namespace std;
/*=====================================================================
剑指 Offer 59 - I. 滑动窗口的最大值
给定一个数组 nums 和滑动窗口的大小 k,请找出所有滑动窗口里的最大值。
示例:
输入: 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
=====================================================================*/
vector<int> maxSlidingWindow(vector<int>& nums, int k)
{
vector<int> maxInWindow;
if (nums.size() >= k && k >= 1)
{
deque<int> index;
for (unsigned int i = 0; i < k; ++i)
{
while (!index.empty() && nums[i] >= nums[index.back()])
{
index.pop_back();
}
index.push_back(i);
}
for (unsigned int i = k; i < nums.size(); ++i)
{
maxInWindow.push_back(nums[index.front()]);
while (!index.empty() && nums[i] >= nums[index.back()])
{
index.pop_back();
}
if (!index.empty() && index.front() <= int(i - k))
{
index.pop_front();
}
index.push_back(i);
}
maxInWindow.push_back(nums[index.front()]);
}
return maxInWindow;
}
/*====================================================================
剑指 Offer 59 - II. 队列的最大值
请定义一个队列并实现函数 max_value 得到队列里的最大值,
要求函数max_value、push_back 和 pop_front 的均摊时间复杂度都是O(1)。
若队列为空,pop_front 和 max_value 需要返回 -1
示例 1:
输入:
["MaxQueue","push_back","push_back","max_value","pop_front","max_value"]
[[],[1],[2],[],[],[]]
输出: [null,null,null,2,1,2]
示例 2:
输入:
["MaxQueue","pop_front","max_value"]
[[],[],[]]
====================================================================*/
template<typename T> class QueueWithMax
{
public:
QueueWithMax() : currentIndex(0)
{
}
void push_back(T number)
{
while (!maximums.empty() && number >= maximums.back().number)
maximums.pop_back();
InternalData internalData = { number, currentIndex };
data.push_back(internalData);
maximums.push_back(internalData);
++currentIndex;
}
void pop_front()
{
if (maximums.empty())
throw new exception("queue is empty");
if (maximums.front().index == data.front().index)
maximums.pop_front();
data.pop_front();
}
T max() const
{
if (maximums.empty())
throw new exception("queue is empty");
return maximums.front().number;
}
private:
struct InternalData
{
T number;
int index;
};
deque<InternalData> data;
deque<InternalData> maximums;
int currentIndex;
};
/*法二---暴力*/
class MaxQueue
{
int q[20000];
int begin = 0, end = 0;
public:
MaxQueue()
{
}
int max_value()
{
int ans = -1;
for (int i = begin; i != end; ++i)
{
ans = max(ans, q[i]);
}
return ans;
}
void push_back(int value)
{
q[end++] = value;
}
int pop_front()
{
if (begin == end)
{
return -1;
}
return q[begin++];
}
};
/*法三--维护一个单调的双端队列*/
class MaxQueue
{
queue<int> q;
deque<int> d;
public:
MaxQueue()
{
}
int max_value()
{
if (d.empty())
return -1;
return d.front();
}
void push_back(int value)
{
while (!d.empty() && d.back() < value)
{
d.pop_back();
}
d.push_back(value);
q.push(value);
}
int pop_front()
{
if (q.empty())
return -1;
int ans = q.front();
if (ans == d.front())
{
d.pop_front();
}
q.pop();
return ans;
}
};
int main()
{
std::cout << "Hello World!\\n";
}
三,测试
以上是关于《剑指Offer——滑动窗口的最大值,队列的最大值》代码的主要内容,如果未能解决你的问题,请参考以下文章