力扣栈题型

删除字符串中的相邻重复项

利用栈的思想来实现,解题链接
在这里插入图片描述

class Solution {
public:
    string removeDuplicates(string S) {
            string stack;
            for(char ch : S)
            {
                if(!stack.empty() && stack.back() == ch)
                {
                    stack.pop_back();
                }
                else
                {
                    stack.push_back(ch);
                }
            }
            return stack;
    }
};

有效括号

在这里插入图片描述
图解链接
在这里插入图片描述

官方解法
利用 栈+哈希表 配合完成

class Solution {
public:
    bool isValid(string s) {
       
        if (s.size() % 2)
            return false;


        unordered_map<char,char> m{
            {')','('},
            {']','['},
            {'}','{'}
        };

        stack <char> st;
        
        for(char ch : s)
        {
            if(m.count(ch))
            {
                 if(st.empty() || st.top() != m[ch] )
                 {
                     return false;
                 }
                 st.pop();
            }
            else
            {
                st.push(ch);
            }
           
        }

        return st.empty();
    }
};

最小栈

官方解法
这思路都不是人想的,完全没想到这么做,不是解题思路不会,是不懂题意,怀疑N+1天

class MinStack {
public:
    /** initialize your data structure here. */
    stack <int> x_stack;
    stack <int> min_stack;

    MinStack() {
        min_stack.push(INT_MAX);   
    }
    
    void push(int val) {
        x_stack.push(val);
        //永远保留最小值
        min_stack.push(min(min_stack.top(),val));
    }
    
    void pop() {
    //x_stack 和 Min_stack 保持同步
        x_stack.pop();
        min_stack.pop();
    }
    
    int top() {
        return x_stack.top();
    }
    
    int getMin() {
        return min_stack.top();
    }
};

/**
 * Your MinStack object will be instantiated and called as such:
 * MinStack* obj = new MinStack();
 * obj->push(val);
 * obj->pop();
 * int param_3 = obj->top();
 * int param_4 = obj->getMin();
 */

用队列实现栈

用两个队列实现栈

在这里插入图片描述

class MyStack {
public:
    queue<int> q1;
    queue<int> q2;
    /** Initialize your data structure here. */
    MyStack() {
        
    }   
    /** Push element x onto stack. */
    void push(int x) {

        //1、自己写的,两次遍历,复杂度偏高了
        // while(!q1.empty())
        // {
        //     q2.push(q1.front());
        //     q1.pop();
        // }
        // q1.push(x);
        // while(!q2.empty())
        // {
        //     q1.push(q2.front());
        //     q2.pop();
        // }

        //2、官方解法,一次遍历,交换容器
       q2.push(x);
       while(!q1.empty())
       {
           q2.push(q1.front());
           q1.pop();

       }

       swap(q1,q2);

    }
    
    /** Removes the element on top of the stack and returns that element. */
    int pop() {
        int r = q1.front();
        q1.pop();
        return r;
    }
    
    /** Get the top element. */
    int top() {    
        return q1.front();
    }
    
    /** Returns whether the stack is empty. */
    bool empty() {
        return q1.empty();
    }
};

时间复杂度:入栈操作 O(n),其余操作都是 O(1)。
入栈操作需要将queu1中的 n 个元素出队,并入队 n+1个元素到queue2,共有2n+1 次操作,每次出队和入队操作的时间复杂度都是 O(1),因此入栈操作的时间复杂度是 O(n)。
出栈操作对应将queue 的前端元素出队,时间复杂度是 O(1)O(1)。
获得栈顶元素操作对应获得 queue1的前端元素,时间复杂度是 O(1)O(1)。
判断栈是否为空操作只需要判断queue 1是否为空,时间复杂度是 O(1)O(1)。
空间复杂度:O(n),其中 n 是栈内的元素。需要使用两个队列存储栈内的元素。

用一个队列实现栈

class MyStack {
public:
    queue<int> q;

    /** Initialize your data structure here. */
    MyStack() {

    }

    /** Push element x onto stack. */
    void push(int x) {
   //关键在于将队列中的已有数据重新取出,移动至队尾
        int n = q.size();
        q.push(x);
        for (int i = 0; i < n; i++) {
            q.push(q.front());
            q.pop();
        }
    }
    
    /** Removes the element on top of the stack and returns that element. */
    int pop() {
        int r = q.front();
        q.pop();
        return r;
    }
    
    /** Get the top element. */
    int top() {
        int r = q.front();
        return r;
    }
    
    /** Returns whether the stack is empty. */
    bool empty() {
        return q.empty();
    }
};
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/implement-stack-using-queues/solution/yong-dui-lie-shi-xian-zhan-by-leetcode-solution/

用栈实现队列

个人解法

两次遍历

class MyQueue {
public:
    stack <int> s1,s2;

    /** Initialize your data structure here. */
    MyQueue() {

    }
    
    /** Push element x to the back of queue. */
    //两次遍历  ,实现 两个 栈之间的数据转移 
    void push(int x) {
        while(!s1.empty())
        {
            s2.push(s1.top());
            s1.pop();
        }
        s1.push(x);
        while(!s2.empty())
        {
            s1.push(s2.top());
            s2.pop();
        }
    }
    
    /** Removes the element from in front of queue and returns that element. */
    int pop() {
        int r = s1.top();
        s1.pop();
        return r;
    }
    
    /** Get the front element. */
    int peek() {
        return s1.top();
    }
    
    /** Returns whether the queue is empty. */
    bool empty() {
        return s1.empty();
    }
};

官方解法

class MyQueue {
private:
    stack<int> inStack, outStack;

    void in2out() {
        while (!inStack.empty()) {
            outStack.push(inStack.top());
            inStack.pop();
        }
    }

public:
    MyQueue() {}

    void push(int x) {
        inStack.push(x);
    }

    int pop() {
        if (outStack.empty()) {
            in2out();
        }
        int x = outStack.top();
        outStack.pop();
        return x;
    }

    int peek() {
        if (outStack.empty()) {
            in2out();
        }
        return outStack.top();
    }

    bool empty() {
        return inStack.empty() && outStack.empty();
    }
};
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/implement-queue-using-stacks/solution/yong-zhan-shi-xian-dui-lie-by-leetcode-s-xnb6/

时间复杂度:push 和 empty 为 O ( 1 ) O(1) O(1),pop 和peek 为均摊O(1),空间复杂度为 O ( n ) O(n) O(n)

去除重复字母

class Solution {
public:
    string removeDuplicateLetters(string s) {
    //num用来记录字符串s 中各个字符的个数
    //vis 用于判断新建的栈中是否已有当前字母,如果有不再入栈,如果没有,入栈,判断当前字符
    //是否小于栈顶字符,若小且原字符串s中依旧有栈顶字符,则将栈顶字符出栈,并清楚标志位,直到
    //当前字符大于栈顶字符
  	//num记录26个字母  在字符串s中的个数,分别记录在对应位置中
       
      
      //vis  统计栈中字符个数
        vector <int> vis(26),num(26);

        // num  统计原字符串中 各个字符的个数
        for(char ch : s)
        {
            num[ch - 'a'] ++;
        }

        string stk;
        for(char ch : s)
        {
            //如果栈中当前字符数为0,压栈,vis自加
            //栈中全部字符不可重复
            if(!vis[ch - 'a'])
            {
                //比较当前字符与栈中字符优先级,优先级小且原字符串中仍有栈顶字符,则出栈
                while(!stk.empty() && stk.back() > ch)
                {
                    //原字符串中仍有栈顶字符
                    if(num[stk.back() - 'a'] > 0)
                    {
                        vis[stk.back() - 'a'] = 0;
                        stk.pop_back();
                    }
                    else
                    {
                        break;
                    }
                }
                vis[ch - 'a'] =1;
                stk.push_back(ch);
            }
            //原字符串字符数自减
            num[ch - 'a'] -= 1;
        }

        return stk;
    }
};

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/remove-duplicate-letters/solution/qu-chu-zhong-fu-zi-mu-by-leetcode-soluti-vuso/
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值