代码随想录算法训练营第十天 | 232.用栈实现队列 225.用队列实现栈 20.有效的括号 1047.删除字符串中的所有相邻重复项

python语法:

一、python不支持栈,通常使用列表(list)来模拟栈。append(),pop()

点击查看代码
stack = []
# 压栈(push)
stack.append(1)
# 弹栈(pop)
top_element = stack.pop()
# 查看栈顶元素(peek)
top_element = stack[-1]
# 检查栈是否为空
is_empty = len(stack) == 0
not stack

二、python常用的数据结构(列表、字典、集合、元组)还有常用模块

  • 列表[]:append(v),insert(idx,v),extend([]) | remove(v),pop(/idx),del list[idx],clear()
点击查看代码
# append()在列表末尾添加一个元素。
my_list = [1, 2, 3]
my_list.append(4)
print(my_list)  # 输出: [1, 2, 3, 4]
# insert()在指定位置插入一个元素。
my_list = [1, 2, 3]
my_list.insert(1, 4)  # 在索引1的位置插入4
print(my_list)  # 输出: [1, 4, 2, 3]
# extend()在列表末尾一次性追加另一个列表中的所有元素。
my_list = [1, 2, 3]
my_list.extend([4, 5])
print(my_list)  # 输出: [1, 2, 3, 4, 5]

# remove()删除列表中第一个匹配的元素。如果元素不存在,会引发 ValueError。
my_list = [1, 2, 3, 2, 4]
my_list.remove(2)
print(my_list)  # 输出: [1, 3, 2, 4]
# pop()删除并返回指定位置的元素。如果不指定位置,则默认删除并返回最后一个元素。
my_list = [1, 2, 3]
popped_element = my_list.pop()
print(popped_element)  # 输出: 3
print(my_list)  # 输出: [1, 2]
popped_element = my_list.pop(0)
print(popped_element)  # 输出: 1
print(my_list)  # 输出: [2]
# del删除指定位置的元素或删除整个列表。
my_list = [1, 2, 3]
del my_list[1]
print(my_list)  # 输出: [1, 3]
del my_list  # 删除整个列表
# print(my_list)  # 这行代码会引发错误,因为my_list已经被删除
# clear()清空列表,删除所有元素。
my_list = [1, 2, 3]
my_list.clear()
print(my_list)  # 输出: []
  • 字典{}:dict['xx']=4
  • 集合{}:add(),remove()
  • 元组():不可变?
  • 高端数据结构'deque'双端队列,pop(),popleft()里面都为空
点击查看代码
from collections import deque

my_deque = deque([1, 2, 3, 4, 5])
my_deque.append(6) # 输出: deque([1, 2, 3, 4, 5, 6])
my_deque.appendleft(0) # 输出: deque([0, 1, 2, 3, 4, 5, 6])
my_deque.pop() # 输出: deque([0, 1, 2, 3, 4, 5])
my_deque.popleft() # 输出: deque([1, 2, 3, 4, 5])

  • 用于计数的字典'Counter'
点击查看代码
from collections import Counter

my_counter = Counter(['a', 'b', 'c', 'a', 'b', 'a'])
print(my_counter)  # 输出: Counter({'a': 3, 'b': 2, 'c': 1})
print(my_counter.most_common(2))  # 输出: [('a', 3), ('b', 2)]

232.用栈实现队列

题目:请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):
实现 MyQueue 类:
void push(int x) 将元素 x 推到队列的末尾
int pop() 从队列的开头移除并返回元素
int peek() 返回队列开头的元素
boolean empty() 如果队列为空,返回 true ;否则,返回 false

解题:

关键:
1.python不支持栈,用两个列表来模拟栈,并且只能用pop,append操作
2.在push数据的时候,只要数据放进输入栈就好,但在pop的时候,操作就复杂一些,输出栈如果为空,就把进栈数据全部导入进来(注意是全部导入),再从出栈弹出数据,如果输出栈不为空,则直接从出栈弹出数据就可以了
3.peek利用pop方法获得队列的前端元素,并且将这个元素存回输出栈保持队列不变,返回元素

点击查看代码
class MyQueue:

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

    def push(self, x: int) -> None:
        self.stack_in.append(x)

    def pop(self) -> int:
        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) -> int:
        ans=self.pop()
        self.stack_out.append(ans)
        return ans

    def empty(self) -> bool:
        return not(self.stack_in or self.stack_out)

225.用队列实现栈

题目:请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。
实现 MyStack 类:
void push(int x) 将元素 x 压入栈顶。
int pop() 移除并返回栈顶元素。
int top() 返回栈顶元素。
boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。

解题:

关键:
1.用双端队列deque,一个队列就可以实现栈
2.一个队列在模拟栈弹出元素的时候只要将队列头部的元素(除了最后一个元素外)全部重新添加到队列尾部,此时再去最左边元素就是栈应该弹出的元素了

点击查看代码
class MyStack:

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

    def push(self, x: int) -> None:
        self.que.append(x)

    def pop(self) -> int:
        for i in range(len(self.que)-1):
            self.que.append(self.que.popleft())
        return self.que.popleft()

    def top(self) -> int:
        ans=self.pop()
        self.que.append(ans)
        return ans

    def empty(self) -> bool:
        return not self.que

20.有效的括号

题目:给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
每个右括号都有一个对应的相同类型的左括号。

解题:

思路:由于栈结构的特殊性,非常适合做对称匹配类的题目。
关键:区分三种情况:
1.左括号多了:遍历完s栈里还有元素; (写在最后)
2.括号不匹配:遍历碰到的右括号类型和栈顶的右括号类型不匹配;
3.右括号多了:还没遍历完要消除时栈却已经空了;

点击查看代码
class Solution:
    def isValid(self, s: str) -> bool:
        if len(s)%2!=0: #剪枝
            return False
        stack=[]
        for i in s:
            if i=='(':
                stack.append(')')
            elif i=='[':
                stack.append(']')
            elif i=='{':
                stack.append('}')
            elif not stack or stack[-1]!=i:
                return False
            else:
                stack.pop()
        if stack:
            return False
        else:
            return True

1047.删除字符串中的所有相邻重复项

题目:给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。
在 S 上反复执行重复项删除操作,直到无法继续删除。
在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。

解题:

思路:相邻且相同的字母,对称匹配问题,用栈秒了

点击查看代码
class Solution:
    def removeDuplicates(self, s: str) -> str:
        stack=[]
        for i in s:
            if stack and stack[-1]==i:
                stack.pop()
            else:
                stack.append(i)
        return ''.join(stack)

心得:

python的栈本质上还是个列表,添加和删除元素的方向都是在列表右边,可以画个右开口的框框来分析
常用操作:append(),pop(),stack[-1]
对于字符串元素的遍历:for i in s:

posted @ 2024-06-15 21:39  Y荷兰豆Y  阅读(5)  评论(0编辑  收藏  举报