1.C++中的栈:
c++stack(堆栈)是一个容器的改编,它实现了一个先进后出的数据结构(FILO)
使用该容器时需要包含#include<stack>头文件;
定义stack对象的示例代码如下:
stack<int>s1;
stack<string>s2;
stack的基本操作有:
1.入栈:如s.push(x);
2.出栈:如 s.pop().注意:出栈操作只是删除栈顶的元素,并不返回该元素。
3.访问栈顶:如s.top();
4.判断栈空:如s.empty().当栈空时返回true。
5.访问栈中的元素个数,如s.size();
2.栈的相关题目:
2.1 leetcode 155 —— Min Stack
class MinStack {
public:
/** initialize your data structure here. */
void push(int x) {
//注意这里一定要是大于等于号 否则若输入为3 2 2 2,最后的2出栈(ss = 3 2 2)则最小值变成了3(因为min中为3 2)
if(ss.empty()||(!min.empty() && min.top() >= x ))
{
min.push(x);
}
ss.push(x);
}
void pop() {
if(ss.top() == min.top())
{
min.pop();
}
ss.pop();
}
int top() {
return ss.top();
}
int getMin() {
return min.top();
}
private:
stack<int> ss;
stack<int> min;//使用一个栈记录到当前ss.top的最小值队列
};
2.2 leetcode 20 —— Valid Parentheses
class Solution {
public:
bool isValid(string s) {
if(s.length() == 0)
{
return true;
}
stack<char> ss;
ss.push(s[0]);
for(int i = 1;i < s.length();i++)
{
if(!ss.empty())
{
if((s[i] == ')' && ss.top() == '(') ||
(s[i] == ']' && ss.top() == '[') ||
(s[i] == '}' && ss.top() == '{'))
{
ss.pop();
continue;
}
}
ss.push(s[i]);
}
if(ss.empty())
{
return true;
}
return false;
}
};
2.3 ***leetcode 94 —— Binary Tree Inorder Traversal
递归解决:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> result;
inorder(root,result);
return result;
}
void inorder(TreeNode* root, vector<int> &result)
{
if(root != NULL)
{
inorder(root->left,result);
result.push_back(root->val);
inorder(root->right,result);
}
}
};
栈解决(其实思路和递归一样):
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
stack<TreeNode*> toTraversal;
vector<int> result;
while(root != NULL || !toTraversal.empty())
{
//遍历左节点
while(root != NULL)
{
toTraversal.push(root);
root = root->left;
}
root = toTraversal.top();
result.push_back(root->val);
toTraversal.pop();
root = root->right;
}
return result;
}
};
2.4 ***leetcode 341 —— Flatten Nested List Iterator
解法1:
参考:https://blog.youkuaiyun.com/Student_xiao_ming/article/details/86525838
不过这么解没有用栈的知识。。。
/**
* // This is the interface that allows for creating nested lists.
* // You should not implement it, or speculate about its implementation
* class NestedInteger {
* public:
* // Return true if this NestedInteger holds a single integer, rather than a nested list.
* bool isInteger() const;
*
* // Return the single integer that this NestedInteger holds, if it holds a single integer
* // The result is undefined if this NestedInteger holds a nested list
* int getInteger() const;
*
* // Return the nested list that this NestedInteger holds, if it holds a nested list
* // The result is undefined if this NestedInteger holds a single integer
* const vector<NestedInteger> &getList() const;
* };
*/
class NestedIterator {
public:
NestedIterator(vector<NestedInteger> &nestedList) {
push_in(nestedList);
}
void push_in(vector<NestedInteger> nestedList)
{
for(auto t:nestedList)
{
if(t.isInteger())
{
result.push_back(t.getInteger());
}
else
{
push_in(t.getList());
}
}
}
int next() {
return result[count++];
}
bool hasNext() {
return (count < result.size());
}
private:
vector<int> result;
int count = 0;
};
/**
* Your NestedIterator object will be instantiated and called as such:
* NestedIterator i(nestedList);
* while (i.hasNext()) cout << i.next();
*/
解法2:用栈实现树形结构/递归
参考:https://blog.youkuaiyun.com/qq508618087/article/details/51111355
这个解法非常棒!
/**
* // This is the interface that allows for creating nested lists.
* // You should not implement it, or speculate about its implementation
* class NestedInteger {
* public:
* // Return true if this NestedInteger holds a single integer, rather than a nested list.
* bool isInteger() const;
*
* // Return the single integer that this NestedInteger holds, if it holds a single integer
* // The result is undefined if this NestedInteger holds a nested list
* int getInteger() const;
*
* // Return the nested list that this NestedInteger holds, if it holds a nested list
* // The result is undefined if this NestedInteger holds a single integer
* const vector<NestedInteger> &getList() const;
* };
*/
class NestedIterator {
public:
NestedIterator(vector<NestedInteger> &nestedList) {
begins.push(nestedList.begin());
ends.push(nestedList.end());
}
int next() {
return begins.top()++->getInteger();
}
bool hasNext() {
while(!begins.empty())
{
if(begins.top() == ends.top())
{
begins.pop();
ends.pop();
}
else
{
auto tmp = begins.top();
if(tmp->isInteger()) return true;
begins.top()++;
begins.push(tmp->getList().begin());
ends.push(tmp->getList().end());
}
}
return false;
}
private:
stack<vector<NestedInteger>::iterator> begins,ends;
};
/**
* Your NestedIterator object will be instantiated and called as such:
* NestedIterator i(nestedList);
* while (i.hasNext()) cout << i.next();
*/
2.5 leetcode 739 —— Daily Temperatures
class Solution {
public:
vector<int> dailyTemperatures(vector<int>& T) {
vector<int> result(T.size());
stack<int> index;
index.push(0);
for(int i = 1;i < T.size();i++)
{
while(!index.empty() && T[index.top()] < T[i])
{
result[index.top()] = i - index.top();
index.pop();
}
index.push(i);
}
while(!index.empty())
{
result[index.top()] = 0;
index.pop();
}
return result;
}
};
2.6 leetcode 103 —— Binary Tree Zigzag Level Order Traversal
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
vector<vector<int>> res;
stack<TreeNode*> lToR;
stack<TreeNode*> rToL;
if(root == NULL)
{
return res;
}
int nLayer = 0;
rToL.push(root);
while(!lToR.empty() || !rToL.empty())
{
vector<int> tmp;
if((nLayer + 1) % 2 == 0)
{
while(!lToR.empty())
{
if(lToR.top()->right!=NULL)
{
rToL.push(lToR.top()->right);
}
if(lToR.top()->left!=NULL)
{
rToL.push(lToR.top()->left);
}
tmp.push_back(lToR.top()->val);
lToR.pop();
}
}
else
{
while(!rToL.empty())
{
if(rToL.top()->left!=NULL)
{
lToR.push(rToL.top()->left);
}
if(rToL.top()->right!=NULL)
{
lToR.push(rToL.top()->right);
}
tmp.push_back(rToL.top()->val);
rToL.pop();
}
}
nLayer++;
res.push_back(tmp);
}
return res;
}
};
2.7 leetcode 150 —— Evaluate Reverse Polish Notation
class Solution {
public:
int evalRPN(vector<string>& tokens) {
stack<int> ss;
int res;
for (int i = 0; i < tokens.size(); i++)
{
if((tokens[i] != "+") && (tokens[i] != "-") && (tokens[i] != "*") && (tokens[i] != "/"))
{
ss.push(atoi(tokens[i].c_str()));
}
else
{
int b = ss.top();
ss.pop();
int a = ss.top();
ss.pop();
int c;
if (tokens[i] == "+")
{
c = a + b;
}
if (tokens[i] == "-")
{
c = a - b;
}
if (tokens[i] == "*")
{
c = a * b;
}
if (tokens[i] == "/")
{
c = a / b;
}
ss.push(c);
}
}
res = ss.top();
return res;
}
};
2.8 ***leetcode 394 —— Decode String
class Solution {
public:
string decodeString(string s) {
if(!s.size())
{
return s;
}
stack<int> stnum;
stack<string> sts;
int num = 0;
string cur;
for(int i = 0;i < s.size();i++)
{
if(s[i] >= '0' && s[i] <= '9')
{
num = num*10 + (s[i] - '0');
}
else if(s[i] == '[')
{
stnum.push(num);
sts.push(cur);
num = 0;
cur.clear();
}
else if((s[i] >= 'a' && s[i] <= 'z') || (s[i] >= 'A' && s[i] <= 'Z'))
{
cur += s[i];
}
else if(s[i] == ']')
{
int ntmp = stnum.top();
stnum.pop();
for(int j = 0;j < ntmp;j++)
{
sts.top() += cur;
}
cur = sts.top();
sts.pop();
}
}
return cur;
}
};
2.9 ***leetcode 42 —— Trapping Rain Water
class Solution {
public:
int trap(vector<int>& height)
{
int ans = 0, current = 0;
stack<int> st;
while (current < height.size()) {
while (!st.empty() && height[current] > height[st.top()]) {
int top = st.top();
st.pop();
if (st.empty())
break;
int distance = current - st.top() - 1;
int bounded_height = min(height[current], height[st.top()]) - height[top];
ans += distance * bounded_height;
}
st.push(current++);
}
return ans;
}
};
2.10 ***leetcode 84 —— Largest Rectangle in Histogram
参考:https://blog.youkuaiyun.com/Zolewit/article/details/88863970
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
int max = 0;
stack<int> ss;
heights.push_back(0);//保证所有柱子的右边都有比它小的值
for(int i = 0;i < heights.size();i++)
{
while(!ss.empty() && heights[i] < heights[ss.top()])
{
int s;
int top = ss.top();
ss.pop();
if(ss.empty())
{
s = heights[top] * i ;
}
else
{
s = heights[top] * (i - ss.top() - 1); //包含top柱子的最大矩形的宽 取决于左右两边小于它的第一个柱子
}
max = s > max ? s : max;
}
ss.push(i);
}
return max;
}
};