代码随想录算法训练营第十一天|栈与队列理论基础,232.用栈是先队列,225.用队列实现栈,20.有效的括号

前几天去参加了婚礼,线下招聘面试会,一个艺术高中的进班试讲和面试(被校长diss了一翻,可那些明明简历关就可以直接把我筛掉,还专门让我线上线下试讲两次,又让我准备各种材料去学校面谈......但这也对我是个很难得的体验,毕竟能站在几十个同学和三四位老师面前,不怎么紧张地上完一整节数学课,写写黑板字,是以前怎么也想不到的,社恐倾向 -= 1)。算法训练营的进度落下好多,这两天尽量补补。

栈与队列理论基础

队列:先进先出。

栈:先进后出。

代码随想录算法训练营第十一天|栈与队列理论基础,232.用栈是先队列,225.用队列实现栈,20.有效的括号_第1张图片

栈与队列的转换思路

栈与队列最大的区别就是pop的原理,下面两个题目是实现它们两个的相互转换,个人感觉是让它们元素储存的顺序转换。栈是先进后出,队列是先进先出,如果用栈来表示队列,需要两个栈,把队列要pop的元素的前面所有都先按顺序从一个栈pop出来到另一个,这样相当于把栈最里面的元素”掏“出来。而当用队列表示栈,将栈顶元素移除时,同样是改变顺序,把列队里外面的元素pop出,一一重新添加到进口,从而把对列队来说最里面的那个元素”顶“出来。

另外要注意当我们只要返回列队/栈的开头/顶端的元素时,使用pop后需要再append上。

题目

232.用栈实现队列

题目链接:232. 用栈实现队列 - 力扣(LeetCode)

题目思路:使用两个栈,一个是输入栈,一个为输出栈。

push:直接将数据放进输入栈、

pop:如果输出栈为空,将输入栈中的全部数据导入输出栈;如果输出栈不为空,则直接从输出栈中弹出数据。 

判断队列是否为空:若输入栈和输出栈都为空,则队列为空。

class MyQueue(object):

    def __init__(self):
        self.stack_in = []
        self.stack_out = []

    def push(self, x):
        self.stack_in.append(x)

    def pop(self):
        if self.empty():
            return None

        if self.stack_out:
            return self.stack_out.pop()
        else:
            for i in range(len(self.stack_in)):
                self.stack_out.append(self.stack_in.pop())

            return self.stack_out.pop()

    def peek(self):
        ans = self.pop()
        self.stack_out.append(ans)

        return ans

    def empty(self):

        return not (self.stack_in or self.stack_out)

225. 用队列实现栈

题目链接:225. 用队列实现栈 - 力扣(LeetCode)

题目思路

pop:将队列头部的元素(除了最后一个)弹出后重新加入队尾列。

top: 把队列最后一个返回/执行pop后,别忘再append。

术语

Python-pop()和popleft()方法_天寒心亦热的博客-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/aaaccc444/article/details/130203557

deque--双端队列

方法:pop()方法用语从队伍右侧(出口)删除元素,并返回被删除的元素。

popleft()方法用于从队列的左侧(进口)删除元素,并返回被删除的元素。

class MyStack(object):

    def __init__(self):
        self.que = deque()

    def push(self, x):
        self.que.append(x)

    def pop(self):
        if self.empty():
            return None
        for i in range(len(self.que) - 1):
            self.que.append(self.que.popleft())
        return self.que.popleft()


    def top(self):
        # 方法一
        '''if self.empty():
            return None
        return self.que[-1]'''
        # 方法二
        ans = self.pop()
        self.que.append(ans)
        return ans



    def empty(self):
        return not (self.que)

20. 有效的括号

题目链接:20. 有效的括号 - 力扣(LeetCode)

第一眼以为左右括号一定是从字列最外往内相匹配的,所以用了双指针,结果发现还有一种形式是“[]{}",这样就没法正确判断了。卡哥提出了栈的方法解决,不得不感慨实在太妙。 

题目思路

从字符串第一个开始遍历,如果遇到左括号,就往栈里加匹配的右括号,遇到右括号,就把栈里的最后一个元素弹出,比较是否相同。

无效的三种情况:

1. 左边括号多余——遍历完字符串之后,栈里面依然有元素。

2. 左右不匹配——弹出的元素和右括号不同。

3.右边括号多余:在遍历过程中遇到右括号,可是栈里面已经空了。

注意:判断这三种情况的语句一定要注意顺序和条件完整。

对于第三种情况,只有当遍历到右括号时,且stack那个时候为空,才无效,如果判断这个情况的语句是在整体的for循环中,则错误,因为在循环的大过程中,stack可以为空(那时正好左右消完了)。

class Solution(object):
    def isValid(self, s):
        stack = []
        for i in range(len(s)):
            if s[i] == "(":
                stack.append(")")
            elif s[i] =="[":
                stack.append(']')
            elif s[i] == "{":
                stack.append('}')
            elif s[i] == ")" or s[i] =="]" or s[i] == "}":
                if stack == []:
                    return False
                element = stack.pop()
                if element != s[i]:
                    return False
            
        if i == len(s) - 1 and stack:
            return False

        return True

你可能感兴趣的:(算法)