Leetcode-栈&队列

20. 有效的括号 https://leetcode-cn.com/problems/valid-parentheses/

给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。

有效字符串需满足:

左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串。

解:

如果来一个左括号,还不能判断是否合法,push进栈;来一个右括号,看一下栈的peek是否匹配,如果匹配就pop出来,否则不合法;如果合法,最后栈应该是空的。

class Solution:
    def isValid(self, s: str) -> bool:
        if s is None:
            return True
        str_map = {")": "(", 
                   "]": "[", 
                   "}": "{"
                  }   # 这里用hashmap存对应关系,右括号放前面
        stack = []
        for char in s:
            if char in str_map:
                if not stack or stack[-1] != str_map[char]:
                    return False
                stack.pop()
            else:
                stack.append(char)
        if stack:
            return False
        return True

  

232. 用栈实现队列 https://leetcode-cn.com/problems/implement-queue-using-stacks/

使用栈实现队列的下列操作:

push(x) -- 将一个元素放入队列的尾部。
pop() -- 从队列首部移除元素。
peek() -- 返回队列首部的元素。
empty() -- 返回队列是否为空。

说明:

你只能使用标准的栈操作 -- 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。
你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。
假设所有操作都是有效的 (例如,一个空的队列不会调用 pop 或者 peek 操作)。

解:

队列先进先出,栈后进先出。用两个栈s1和s2实现队列。

入队O(n),push的元素要后出,那就要把push的元素放到栈底。所以每次入队一个元素,要先把s1中的元素移到s2中,把入队元素push到s1中,再把s2中的元素移回s1。

出队O(1),直接从s1中pop出去即可,因为后入队的元素在s1的底部,先入队的元素在s1顶部。

取队首元素,s1的顶部元素,即最先入队的元素。

判空,元素全部存在s1中,判空s1即可。

class MyQueue:

    def __init__(self):
        """
        Initialize your data structure here.
        """
        self.s1 = []
        self.s2 = []
        

    def push(self, x: int) -> None:
        """
        Push element x to the back of queue.
        """
        if self.empty():
            self.s1.append(x)
        else:
            while self.s1:
                self.s2.append(self.s1.pop())
            
            self.s1.append(x)
            
            while self.s2:
                self.s1.append(self.s2.pop())
        

    def pop(self) -> int:
        """
        Removes the element from in front of queue and returns that element.
        """
        if not self.empty():
            return self.s1.pop()
        

    def peek(self) -> int:
        """
        Get the front element.
        """
        if not self.empty():
            return self.s1[-1]
        

    def empty(self) -> bool:
        """
        Returns whether the queue is empty.
        """
        return False if self.s1 else True

 

第二种方法,入队O(1),出队摊还复杂度O(1)。

入队,直接push进s1的栈顶。

出队,把s1中全部元素弹出,压入s2,这样s1的栈底元素变成了s2的栈顶元素,直接pop出去即可。一旦s2变空了,只需要把s1中的元素再一次转移到s2即可。在最坏情况下,s2为空,需要从s1中弹出n个元素,然后再把这n个元素压入s2,在这里n代表队列的大小。这个过程产生了2n步操作,时间复杂度为 O(n)。但当s2非空时,就只有 O(1)O(1) 的时间复杂度。

取队首元素,定义front变量来存队首元素,如果s2为空,front就是队首元素(即s1的栈底元素),否则s2的栈顶元素为队首元素。

判空,s1和s2都有队列的元素,都为空则队列空。

class MyQueue:

    def __init__(self):
        """
        Initialize your data structure here.
        """
        self.s1 = []
        self.s2 = []
        self.front = None
        

    def push(self, x: int) -> None:
        """
        Push element x to the back of queue.
        """
        if not self.s1:
            self.front = x
        self.s1.append(x)
        

    def pop(self) -> int:
        """
        Removes the element from in front of queue and returns that element.
        """
        if not self.empty():
            if not self.s2:  # 如果s2为空,把s1中元素全部转移过来,再pop; s2不空,直接pop
                while self.s1:
                    self.s2.append(self.s1.pop())
            return self.s2.pop()
                    
    def peek(self) -> int:
        """
        Get the front element.
        """
        if not self.empty():
            return self.s2[-1] if self.s2 else self.front
        

    def empty(self) -> bool:
        """
        Returns whether the queue is empty.
        """
        if not self.s1 and not self.s2:
            return True
        return False 

  

225. 用队列实现栈 https://leetcode-cn.com/problems/implement-stack-using-queues/

使用队列实现栈的下列操作:

push(x) -- 元素 x 入栈
pop() -- 移除栈顶元素
top() -- 获取栈顶元素
empty() -- 返回栈是否为空


注意:

你只能使用队列的基本操作-- 也就是 push to back, peek/pop from front, size, 和 is empty 这些操作是合法的。
你所使用的语言也许不支持队列。 你可以使用 list 或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。
你可以假设所有操作都是有效的(例如, 对一个空的栈不会调用 pop 或者 top 操作)。

解:

两个队列 q1 和 q2 实现栈。

压栈 O(1),进栈元素就直接入队q1

出栈 O(n),要pop的元素是最后入队的元素,

个队列用作临时存储 q1 中出队的元素。q2中最后入队的元素将作为新的栈顶元素。接着将q1中最后剩下的元素出队。通过把q1和q2互相交换的方式来避免把q2中的元素往q1中拷贝。

取栈顶元素:栈的top始终为q1的队尾,即最后一个压栈的元素。

判空:栈中元素都在q1中

class MyStack:

    def __init__(self):
        """
        Initialize your data structure here.
        """
        self.q1 = []
        self.q2 = []
        self.top_elem = None

    def push(self, x: int) -> None:
        """
        Push element x onto stack.
        """
        self.q1.append(x)
        self.top_elem = x
        
    def pop(self) -> int:
        """
        Removes the element on top of the stack and returns that element.
        """
        while len(self.q1) > 1:
            self.top_elem = self.q1.pop(0) 
            self.q2.append(self.top_elem)  # q1中最后一个元素之前的元素全部出队,入队q2,栈的新top就是q2的队尾
            
        tmp = self.q1.pop(0)  # q1原队尾出队,相当于栈pop出去栈顶元素
        self.q1, self.q2 = self.q2, self.q1
        return tmp
        

    def top(self) -> int:
        """
        Get the top element.
        """
        return self.top_elem
        

    def empty(self) -> bool:
        """
        Returns whether the stack is empty.
        """
        return False if self.q1 else True

  

第二种方法,两个队列,压入O(n),弹出O(1)

压栈:让每一个新元素从q2入队,同时把这个元素作为栈顶元素保存。当q1非空(也就是栈非空),让q1中所有的元素全部出队,再将出队的元素从 q2 入队。通过这样的方式,新元素(栈中的栈顶元素)将会在q2的前端。通过将q1,q2互相交换的方式来避免把q2中的元素往q1中拷贝。

出栈:栈不空(q1不空),q1队首元素出队即可。更新一下栈顶元素为新的q1队首元素

判空:q1不空即可

取栈顶元素:如果q1为空,那栈为空,栈顶元素为null;如果q1不空,栈顶元素就是q1的队首元素。(因为q1中元素是后进栈的放队首)

class MyStack:

    def __init__(self):
        """
        Initialize your data structure here.
        """
        self.q1 = []
        self.q2 = []
        self.top_elem = None

    def push(self, x: int) -> None:
        """
        Push element x onto stack.
        """
        self.q2.append(x)
        self.top_elem = x
        while self.q1:
            self.q2.append(self.q1.pop(0))
        self.q1, self.q2 = self.q2, self.q1
        
    def pop(self) -> int:
        """
        Removes the element on top of the stack and returns that element.
        """
        if not self.empty():
            tmp = self.q1.pop(0)
            if self.q1:
                self.top_elem = self.q1[0]
            else:
                self.top_elem = None
            return tmp
        

    def top(self) -> int:
        """
        Get the top element.
        """
        return self.top_elem
        

    def empty(self) -> bool:
        """
        Returns whether the stack is empty.
        """
        return False if self.q1 else True

  

猜你喜欢

转载自www.cnblogs.com/chaojunwang-ml/p/11349179.html