代码随想录算法训练营第九天(栈与队列篇)|Leetcode232用栈实现队列,Leetcode225用队列实现栈,Leetcode20有效的括号,Leetcode1047删除字符串中的所有相邻重复项
Leetcode 232 用栈实现队列
题目链接: 用栈实现队列
使用两个栈实现一个队列类,要求实现队列的基本功能: (push, peek, pop, and empty)
思路: 首先我们回忆栈与队列的特征。栈先进后出,队列先进先出。为了用栈模拟队列先进先出的特性,我们需要使用两个栈进行操作,分别是出栈 (outStack) 和入栈 (inStack)。当插入元素时,首先将元素插入到入栈中。等要弹出或查看队头元素时,将入栈中的所有元素弹出,并插入到出栈中,从而实现元素顺序的调换。此时出栈栈顶的元素即为模拟的队列的队头元素。
具体代码实现
class MyQueue:
def __init__(self):
self.inStack = []
self.outStack = []
def push(self, x: int) -> None:
self.inStack.append(x)
def pop(self) -> int: # 此处需要注意,仅当出栈中为空时,才将入栈中所有元素弹出,移动到出栈中。否则会破坏原有元素之间的顺序
if not self.outStack:
while self.inStack:
self.outStack.append(self.inStack.pop())
return self.outStack.pop()
def peek(self) -> int:
if not self.outStack:
while self.inStack:
self.outStack.append(self.inStack.pop())
return self.outStack[-1]
def empty(self) -> bool: # 出栈和入栈都为空时,队列为空
return not self.inStack and not self.outStack
Leetcode 225 用队列实现栈
题目链接: 用队列实现栈
仅使用一个队列,模拟栈的基本操作(push, top, pop, and empty)
思路: 用队列模拟栈与用栈模拟队列的思路有所不同,由于只有一个队列,我们可以用环形队列模拟栈的操作,即将队首的元素取出后,重新插入队尾。
class MyStack:
def __init__(self):
from collections import deque
self.size = 0 # 维护栈大小
self.myqueue = deque()
def push(self, x: int) -> None:
self.myqueue.append(x)
self.size += 1
def pop(self) -> int:
for i in range(self.size-1): # 将前(size-1)个元素从队头移动到队尾,随后将最后一个元素移出队列,模拟出栈操作
self.myqueue.append(self.myqueue.popleft())
target = self.myqueue.popleft()
self.size -= 1
return target
def top(self) -> int:
for i in range(self.size-1):
self.myqueue.append(self.myqueue.popleft())
target = self.myqueue.popleft()
self.myqueue.append(target)
return target
def empty(self) -> bool:
return self.size == 0
Leetcode 20 有效的括号
题目链接: 有效的括号
给定一个仅包含以下字符('(', ')', '[', ']', '{', '}')的字符串 s
,判断括号是否有效匹配。
要求:左括号必须匹配同类型的右括号,且左括号必须按照正确的顺序匹配右括号,而对于右括号,也必须存在相应的左括号与其匹配,如"()" 和 "()[]{}" 是有效的括号字符串,但 "(]" 和 "([)]" 不是。
思路: 该问题符合栈 先进后出
的特性,非常适合利用栈求解。我们可以遍历字符串,在遇到左括号时将左括号入栈,随后在遇到右括号时判断栈顶括号是否匹配。
具体代码实现
class Solution:
def isValid(self, s: str) -> bool:
myStack = []
mapping = {')': '(', '}': '{', ']': '['}
for ch in s:
if ch in mapping:
top_element = myStack.pop() if myStack else '#'
if mapping[ch] != top_element:
return False
else:
myStack.append(ch)
return not myStack
Leetcode 1047 删除字符串中所有的相邻重复
题目链接: 删除字符串中所有的相邻重复
给定一个字符串,要求删除该字符串中所有出现的相邻重复元素。如对于字符串 "abbaxa",首先删去相邻重复元素 "bb",剩下 "aaxa",随后又删去相邻重复元素 "aa",得到最终结果 "xa"
思路: 该题目的特性符合栈 后入先出
的特性,与上一题类似,同样适合使用栈解决。遍历字符串中所有元素,比较当前元素和栈顶元素,若相同则弹出栈顶元素,若不同则压入栈中,最后将栈中元素拼接成字符串返回即可
具体代码实现:
class Solution:
def removeDuplicates(self, s: str) -> str:
myStack = []
for ch in s:
if myStack and myStack[-1] == ch:
while myStack and myStack[-1] == ch:
myStack.pop()
else:
myStack.append(ch)
result = []
while myStack:
result.append(myStack.pop())
return ''.join(result)[::-1]