代码随想录算法训练营第十天 | 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: