c++ 数据结构——栈

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;
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值