训练题:滑动窗口最大值
题目:https://leetcode-cn.com/problems/hua-dong-chuang-kou-de-zui-da-zhi-lcof/
思路:k个数里的最大值,首先想到堆,不过搞半天没出路,转移到考虑队列的数据结构。
max队列,快速获取当前队列的最大值。
- 时间复杂度:O(n)
- 空间复杂度:考虑返回值:O(n);不考虑返回值O(k)。
class MaxQueue {
public:
MaxQueue() {
}
int max_value() {
if(maxQueue.empty()) return -1;
return maxQueue.front();
}
void push(int value) {
dataQueue.push(value);
for(; !maxQueue.empty() && maxQueue.back() < value; maxQueue.pop_back());
maxQueue.push_back(value);
}
int pop() {
if(dataQueue.empty()) return -1;
int ret = dataQueue.front();
dataQueue.pop();
if(maxQueue.front() == ret) maxQueue.pop_front();
return ret;
}
private:
queue<int> dataQueue;
deque<int> maxQueue;
};
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
if(k > nums.size() || nums.empty()) return {};
const auto size = nums.size();
vector<int> ret;
MaxQueue q;
int idx;
for(idx = 0; idx < k; ++idx) q.push(nums[idx]);
ret.push_back(q.max_value());
for(; idx < size; ++idx){
q.push(nums[idx]);
q.pop();
ret.push_back(q.max_value());
}
return ret;
}
};
训练题:max队列
题目:https://leetcode-cn.com/problems/dui-lie-de-zui-da-zhi-lcof/
class MaxQueue {
public:
MaxQueue() {
}
int max_value() {
if(maxQueue.empty()) return -1;
return maxQueue.front();
}
void push_back(int value) {
dataQueue.push(value);
for(; !maxQueue.empty() && maxQueue.back() < value; maxQueue.pop_back());
maxQueue.push_back(value);
}
int pop_front() {
if(dataQueue.empty()) return -1;
int ret = dataQueue.front();
dataQueue.pop();
if(maxQueue.front() == ret) maxQueue.pop_front();
return ret;
}
private:
queue<int> dataQueue;
deque<int> maxQueue;
};
训练题:min栈
class MinStack {
public:
/** initialize your data structure here. */
MinStack() {
}
void push(int x) {
stk.push(x);
// 如果minStk栈顶的最小值没比待插入的x更小,那就要更新最小值了。
if(minStk.empty() || x <= minStk.top()) minStk.push(x);
}
void pop() {
if(stk.empty()) return;
if(stk.top() == minStk.top()) minStk.pop();
stk.pop();
}
int top() {
return stk.top();
}
int min() {
return minStk.top();
}
private:
stack<int> minStk;
stack<int> stk;
};
训练题:压栈/弹栈序列
方法一
bool validateStackSequences( vector<int> &pushed, vector<int> &popped )
{
if( pushed.size() != popped.size() ) { return false; }
stack<int> stk;
int popIdx = 0;
for( const auto &i : pushed )
{
stk.push( i );
while( !stk.empty() && stk.top() == popped[popIdx] )
{
stk.pop();
++popIdx;
}
}
return stk.empty();
}
方法二:模拟法
bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
if(pushed.size() != popped.size()) return false;
const auto size_push = pushed.size();
const auto size_pop = popped.size();
stack<int> s;
int popIdx = 0;
for(int pushIdx = 0; popIdx < size_pop;)
{
for(; (s.empty() || s.top() != popped[popIdx]) && pushIdx < size_push; ++pushIdx )
s.push(pushed[pushIdx]);
if(!s.empty() && s.top() == popped[popIdx]){
s.pop();
++popIdx;
}
else if(pushIdx == size_push) return false;
}
return popIdx == size_pop;
}
训练题:两个栈实现队列
class CQueue
{
public:
CQueue()
{
}
void appendTail( int value )
{
stack1.push( value );
}
int deleteHead()
{
if( stack2.empty() ) for( ; !stack1.empty(); stack1.pop() ) { stack2.push( stack1.top() ); }
int ret = -1;
if( !stack2.empty() )
{
ret = stack2.top();
stack2.pop();
}
return ret;
}
private:
stack<int> stack1;
stack<int> stack2;
};