数据结构与算法leetcode 刷题008 栈和队列的内容

今天刷的内容全都是leetcode中栈和队列的使用

leetcode20:判断是否是匹配括号等;

class Solution {
public:
    bool isValid(string s) {
        int size=s.length();
        if(size%2!=0){
            return false;
        }
        stack<char> Stack;//构建一个stack
        int i;
        for(i=0;i<size;i++){
            if(s[i]=='('||s[i]=='{'||s[i]=='['){
                Stack.push(s[i]);
            }
            else{
                if(Stack.empty())
                    return false;
                if((Stack.top()=='('&&s[i]==')')||(Stack.top()=='{'&&s[i]=='}')||(Stack.top()=='['&&s[i]==']'))
                    Stack.pop();
            }
            
        }
        if(Stack.empty()){
            return true;
        }
        else
            return false;    
    }
};

构建一个栈数据结构来存储相应的数据,如果是左括号就入栈,如果是右括号就出栈,直到所有元素都遍历,如果栈不为空则返回false;

leetcode150:波特兰后续表达式计算,学习的内容是atoi()函数的使用;,时间复杂度都是O(n);

class Solution {
public:
    int evalRPN(vector<string>& tokens) {
        int size=tokens.size();
        if(size==1){
            return atoi(tokens[0].c_str());
        }
        stack<int> ss;
        int i=0;
        for(i;i<size;i++){
            if(tokens[i] != "+" && tokens[i] != "-" && tokens[i] != "*" && tokens[i] != "/"){
                //首先将字符串转换为C字符串,然后转换为int类型的数据
                ss.push(atoi(tokens[i].c_str()));
            }
            else{
                int m=ss.top();
                ss.pop();
                int n=ss.top();
                ss.pop();
                if(tokens[i]=="+") ss.push(m+n);
                if(tokens[i]=="-") ss.push(n-m);
                if(tokens[i]=="*") ss.push(m*n);
                if(tokens[i]=="/") ss.push(n/m);
            }
        }
        return ss.top();
};

leetcode71:简化一个字符串linux文件路径的字符串:

class Solution {
public:
    string simplifyPath(string path) {
        //简化路径名称 使用一个栈来维护字符串
        int size=path.size();
        int i=0;
        
        if(path=="") return "";
        stack<string> stacks;
        //首先遍历所有的字符串中的字符
        for(i=0;i<size;){
            while(i<size&&path[i]=='/'){
                i++;
            }
            string s="";
            while(i<size&&path[i]!='/'){
                s+=path[i++];
            }
            if(s==".."&&!stacks.empty()){
                stacks.pop();// 如果是..弹出相应的元素
            }
            else{
                if(s!=".."&&s!="."&&s!=""){
                    stacks.push(s);
                }
            }
        }
        if(stacks.empty()){
            return "/";//如果当前的栈为空 返回当前路径
        }
        string ans="";
        while(!stacks.empty())
        {
            ans="/"+stacks.top()+ans;
            stacks.pop();
        }
        return ans;
        
    }
};

算法的和时间复杂度为O(n);

栈和递归的紧密联系:与二叉树的使用;

leetcode144; 先序遍历算法的使用

1:递归算法的简单实现:

class Solution {
public:
    vector<int> ans;//增加一个类变量来维护相应的数据
public:
        if(root){
            ans.push_back(root->val);
            preorderTraversal(root->left);
            preorderTraversal(root->right);
        }
        return ans;
    }
};

居然能通过 运算时间是4ms

2.自己模拟一个栈了维护相应的数据;

struct command{
    string flag;
    TreeNode* node;
    command(string ss,TreeNode *Node):flag(ss),node(Node){}
};//主机构建一个结构体来存储相应的Node节点还有一个flag标志
class Solution {
public:
    vector<int> ans;
public:
    vector<int> preorderTraversal(TreeNode* root) {
        
    //使用栈来模拟递归算法的使用;
    if(root==NULL){
        return ans;
    }
    stack<command> result;
    result.push(command("go",root));//首先将根节点入栈中
    while(!result.empty()){
        command top=result.top();
        result.pop();
        if(top.flag=="out"){
            ans.push_back((top.node)->val);
        }
        else{//对于每一次节点都要进行相应的入栈
            if(top.node->right!=NULL){
                result.push(command("go",top.node->right));
            }
            if(top.node->left!=NULL){
                result.push(command("go",top.node->left));
            }
            result.push(command("out",top.node));
        }
    }
     return ans;   
    }
};

以上的运行时间为3ms

3:采用书本中的构建栈的方式较为复杂:

 vector<int> preorderTraversal(TreeNode* root) {
        vector<int> ans;
        TreeNode *p=root;
        if(root==NULL){
            return ans;
        }
        stack<TreeNode *> ss;
        while(p!=NULL||!ss.empty()){
            while(p!=NULL){
                ans.push_back(p->val);
                ss.push(p);
                p=p->left;
                
            }//首先遍历左行节点到最根部,然后再push进右节点;
            if(!ss.empty()){
                TreeNode *q=ss.top();
                ss.pop();
                p=q->right;
            }
        }
        return ans;
}

同理相应的中序遍历的方式也是一样的:

leetcode94:
递归实现:

class Solution {//中序遍历算法
public:
    vector<int> ans;//同样设置一个类属性来存储相应的返回值
    vector<int> inorderTraversal(TreeNode* root) {
        if(root){
            inorderTraversal(root->left);
            ans.push_back(root->val);
            inorderTraversal(root->right);
        }
        return ans;
    }
};

2.模拟栈来实现递归

struct command{
    string val;
    TreeNode *Node;
    command(string val,TreeNode *node):val(val),Node(node){}
};
class Solution {//中序遍历算法
public:
    vector<int> ans;
    vector<int> inorderTraversal(TreeNode* root) {
//         //递归调用 但是返回值的问题需要解决  返回的是vector<int> 类型的数据
//         /*
//         vector<int> ans;
//         if(root==NULL){
//             return ans.push_back(NULL);
//         }
//         else{
//             ans.push_back(root->val);
//             ans.push_back(inorderTraversal(root->left));
//             ans.push_back(inorderTranvesal(root->right));
//         }
//         */
//         vector<int> ans;
//         TreeNode *p=root;
//         if(p==NULL){
//             return ans;// 
//         }
//         stack<TreeNode *> stackss;
//         while(p!=NULL||!stackss.empty()){
//             while(p!=NULL){
//                 stackss.push(p);
//                 p=p->left;//首先找到最左边的子节点;
//             }
//             if(!stackss.empty()){
//             TreeNode *q=stackss.top();
//             ans.push_back(q->val);
//             stackss.pop();
//             p=q->right;
//             }
            
//         }
//         return ans;
        // if(root){
        //     inorderTraversal(root->left);
        //     ans.push_back(root->val);
        //     inorderTraversal(root->right);
        // }
        // return ans;
        if(root==NULL){
            return ans;
        }
        stack<command> ss;
        ss.push(command("go",root));
        while(!ss.empty()){
            command top=ss.top();
            ss.pop();
            if(top.val=="cout"){
                ans.push_back(top.Node->val);
            }
            else{
                if(top.Node->right!=NULL){
                ss.push(command("go",top.Node->right));}
                ss.push(command("cout",top.Node));
                if(top.Node->left!=NULL){
                    ss.push(command("go",top.Node->left));}
            }
        }
        return ans;
    }
};


同理后续遍历采用新的方式也是可以实现:这里不再做详细的介绍了;


队列的内容;

主要是关于树的层序遍历和无权图的最短路径;

leetcode102:
关于树的层序遍历方式;

class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        //使用队列的数据结构来存储相应的结点,每当有节点pop出去就向队尾中添加结点
        //C++中队列的数据结构是Queue
        vector<vector<int>> ans;
        if(root==NULL){
            return ans;
        }
        queue<TreeNode *> result;//首先将相应的root元素入队
        result.push(root);
        while(!result.empty()){
          //构建一个行的队列,用来存储相应的队列中临时数据
            vector<int> tempVector;
            queue<TreeNode *> tempQueue;
            while(!result.empty()){
                TreeNode *front=result.front();
                result.pop();
                tempVector.push_back(front->val);
                if(front->left!=NULL){
                    tempQueue.push(front->left);
                }
                if(front->right!=NULL){
                    tempQueue.push(front->right);
                }
            }
            ans.push_back(tempVector);
            result=tempQueue;
        }
        return ans;
    }
};

leetcode103:层序遍历树,当时树的遍历方式是zip zap的方式Z的方式来遍历树

class Solution {
public:
    vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
        //方法相同还是使用队列的数据结构来进行存储相应的数据;
        //设置一个flag来表示技术如何加入队列中
        queue<TreeNode *> result;
        vector<vector<int>> ans;
        if(root==NULL){
            return ans;
        }
        int flag=1;
        result.push(root);
        while(!result.empty()){
            queue<TreeNode*> temp;
            vector<int> tempVector;
            while(!result.empty()){
                TreeNode *top=result.front();
                result.pop();
                tempVector.push_back(top->val);  
                if(top->left!=NULL){
                    temp.push(top->left);
                    }
                if(top->right!=NULL){
                    temp.push(top->right);
                    }
                }
            
            if(flag==1){
                ans.push_back(tempVector);
                flag=0;}
            else{
                reverse(tempVector.begin(),tempVector.end());
                ans.push_back(tempVector);
                flag=1;}
            result=temp;}
    
           
        return ans;
    }
};


猜你喜欢

转载自blog.csdn.net/hufanglei007/article/details/79517290