棧和佇列
- 232.用棧實現佇列
雙棧的想法。需要在出棧時轉移棧中元素到另一個棧,入棧時轉移棧中元素到初始的棧。
class MyQueue {
public:
stack<int> instack,outstack;
MyQueue() {
}
void push(int x) {
while(!outstack.empty())
{
int element = outstack.top();
outstack.pop();
instack.push(element);
}
instack.push(x);
}
int pop() {
while(!instack.empty())
{
int element = instack.top();
instack.pop();
outstack.push(element);
}
int ans = outstack.top();
outstack.pop();
return ans;
}
int peek() {
while(!instack.empty())
{
int element = instack.top();
instack.pop();
outstack.push(element);
}
int ans = outstack.top();
return ans;
}
bool empty() {
return instack.empty() && outstack.empty();
}
};
/**
* Your MyQueue object will be instantiated and called as such:
* MyQueue* obj = new MyQueue();
* obj->push(x);
* int param_2 = obj->pop();
* int param_3 = obj->peek();
* bool param_4 = obj->empty();
*/
- 225.用佇列實現棧
同雙棧法。
class MyStack {
public:
queue<int> a;
queue<int> b;
MyStack() {
}
void push(int x) {
a.push(x);
}
int pop() {
while(a.size()>1)
{
b.push(a.front());
a.pop();
}
int ans=a.back();
a.pop();
while(!b.empty())
{
a.push(b.front());
b.pop();
}
return ans;
}
int top() {
int ans=a.back();
while(!a.empty())
{
b.push(a.front());
a.pop();
}
while(!b.empty())
{
a.push(b.front());
b.pop();
}
return ans;
}
bool empty() {
return a.empty();
}
};
/**
* Your MyStack object will be instantiated and called as such:
* MyStack* obj = new MyStack();
* obj->push(x);
* int param_2 = obj->pop();
* int param_3 = obj->top();
* bool param_4 = obj->empty();
*/
- 1441.用棧操作構建陣列
一個個對比需要的數字就行。
class Solution {
public:
vector<string> buildArray(vector<int>& target, int n) {
int counter = 0;
vector<string> operations;
for (int i = 1; i <= n; i++)
{
// Match the elements;
if(counter >= target.size()) break;
operations.emplace_back("Push");
if (i == target[counter])
{
counter ++;
continue;
}
else
{
operations.emplace_back("Pop");
}
}
return operations;
}
};
單調棧
棧內部單調遞增或單調遞減的棧。可以用來記錄一些關於可覆蓋面積,最近的符合某些條件的下標資訊等等。
例如我們有:
[6,7,5,2,4,5,9,3]
從左到右尋找左邊第一個比自己小的元素,則可以使用單調棧。
所以:
[-1,0,-1,-1,3,4,5,3]
從右向左尋找右邊第一個比自己小的元素,則有:
[2,2,3,8,7,7,7,8]
例如:我們有這樣一道題
84. 柱狀圖中最大的矩形
這時候我們可以利用單調棧來尋找一根柱子能夠覆蓋的最大範圍。
從左向右遍歷,當新的元素小於等於棧頂元素時不斷出棧,直到棧空或棧頂元素小於當前元素為止。將索引入棧。
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
int n = heights.size();
vector<int> left(n), right(n); // Initialize the vector;
stack<int> mono_stack;
for (int i=0;i<n;i++)
{
// non-empty and the top of the mono-stack is bigger than heights:
while(!mono_stack.empty() && heights[mono_stack.top()] >= heights[i])
{
mono_stack.pop();
}
// When the top is smaller or none in mono_stack, put the values.
left[i] = (mono_stack.empty() ? -1 : mono_stack.top());
mono_stack.push(i);
}
mono_stack = stack<int>();
for (int i=n-1;i > -1 ;i--)
{
// non-empty and the top of the mono-stack is bigger than heights:
while(!mono_stack.empty() && heights[mono_stack.top()] >= heights[i])
{
mono_stack.pop();
}
// When the top is smaller or none in mono_stack, put the values.
right[i] = (mono_stack.empty() ? n : mono_stack.top());
mono_stack.push(i);
}
int ans = 0;
for (int i = 0; i < n; i++)
{
ans = max(ans, heights[i] * (right[i]-left[i]-1));
}
return ans;
}
};
- 84. 柱狀圖中最大的矩形
題解一:單調棧
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
int n = heights.size();
vector<int> left(n), right(n); // Initialize the vector;
stack<int> mono_stack;
for (int i=0;i<n;i++)
{
// non-empty and the top of the mono-stack is bigger than heights:
while(!mono_stack.empty() && heights[mono_stack.top()] >= heights[i])
{
mono_stack.pop();
}
// When the top is smaller or none in mono_stack, put the values.
left[i] = (mono_stack.empty() ? -1 : mono_stack.top());
mono_stack.push(i);
}
mono_stack = stack<int>();
for (int i=n-1;i > -1 ;i--)
{
// non-empty and the top of the mono-stack is bigger than heights:
while(!mono_stack.empty() && heights[mono_stack.top()] >= heights[i])
{
mono_stack.pop();
}
// When the top is smaller or none in mono_stack, put the values.
right[i] = (mono_stack.empty() ? n : mono_stack.top());
mono_stack.push(i);
}
int ans = 0;
for (int i = 0; i < n; i++)
{
ans = max(ans, heights[i] * (right[i]-left[i]-1));
}
return ans;
}
};
最佳化
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
int n = heights.size(),ans=0;
stack<int> mono_stack;
mono_stack.push(-1);
for (int i=0;i<n;i++)
{
while(mono_stack.top()!=-1 && heights[i] < heights[mono_stack.top()])
{
int cur_height = heights[mono_stack.top()];
mono_stack.pop();
ans = max(ans, cur_height*(i - mono_stack.top() - 1));
}
mono_stack.push(i);
}
while(mono_stack.top()!=-1)
{
int cur_height = heights[mono_stack.top()];
mono_stack.pop();
ans = max(ans, cur_height*((n - 1) - mono_stack.top()));
}
return ans;
}
};