AB1 栈
请你实现一个栈。
操作:
push x:将 加𝑥入栈,保证 𝑥为 int 型整数。
pop:输出栈顶,并让栈顶出栈。
top:输出栈顶,栈顶不出栈。
输入:第一行为一个正整数 𝑛,代表操作次数。
输出:
如果操作为push,则不输出任何东西。
如果为另外两种,若栈为空,则输出 "error“。
否则按对应操作输出。
class stack:
def __init__(self):
self.items = []
def push(self, item):
self.items.append(item)
def pop(self):
return self.items.pop()
def top(self):
return self.items[len(self.items)-1]
def size(self):
return len(self.items)
s = stack()
num = input()
for _ in range(int(num)):
a = input()
if a.split()[0] == "push":
b = a.split()[1]
s.push(b)
elif a == "pop":
if s.size() == 0:
print("error")
else:
print(s.pop())
elif a == "top":
if s.size() == 0:
print("error")
else:
print(s.top())
AB2 栈的压入、弹出序列
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。
示例:
输入:[1,2,3,4,5],[4,5,3,2,1]返回值:true
说明:可以通过push(1)=>push(2)=>push(3)=>push(4)=>pop()=>push(5)=>pop()=>pop()=>pop()=>pop()这样的顺序得到[4,5,3,2,1]这个序列,返回true
class Solution:
def IsPopOrder(self , pushV: List[int], popV: List[int]) -> bool:
# write code here
temp = []
j = 0
for i in range(len(pushV)):
while j < len(pushV) and (len(temp) == 0 or temp[-1] != popV[i]):
temp.append(pushV[j])
j += 1
if temp[-1] == popV[i]:
temp.pop()
else:
return False
return True
注:辅助栈为空或者栈顶元素不等于出栈数组当前元素,就持续将入栈数组加入栈中。
AB3 有效括号序列
给出一个仅包含字符’(‘,’)‘,’{‘,’}‘,’[‘和’]',的字符串,判断给出的字符串是否是合法的括号序列括号必须以正确的顺序关闭,"()“和”()[]{}“都是合法的括号序列,但”(]“和”([)]"不合法。
class Solution:
def isValid(self , s: str) -> bool:
# write code here
pushV = []
for i, char in enumerate(s):
if char == "(": pushV.append(")")
elif char == "[": pushV.append("]")
elif char == "{": pushV.append("}")
elif len(pushV) == 0:
return False
elif pushV[-1] == char:
pushV.pop()
return len(pushV) == 0
AB4 逆波兰表达式求值
给定一个逆波兰表达式,求表达式的值。
示例:
输入:[“2”,“1”,“+”,“4”,“*”] 返回值:12
class Solution:
def evalRPN(self , tokens: List[str]) -> int:
# write code here
stack = []
for i in tokens:
if i in "+-*/":
a = stack.pop()
b = stack.pop()
if i == "+":
stack.append(b+a)
elif i == "-":
stack.append(b-a)
elif i == "*":
stack.append(b*a)
elif i == "/":
stack.append(int(b/a))
else: stack.append(int(i))
return stack[0]
遇到操作数则入栈,遇到运算符,则从弹出两个操作数进行计算,并将结果再存入栈中
注:这道题的除非运算,必须取整(四舍五入),即用int(b/a),而不能用b//a,双斜杠都是向下取整。
AB5 点击消除
牛牛拿到了一个字符串。
他每次“点击”,可以把字符串中相邻两个相同字母消除,例如,字符串"abbc"点击后可以生成"ac"。
但相同而不相邻、不相同的相邻字母都是不可以被消除的。
牛牛想把字符串变得尽可能短。他想知道,当他点击了足够多次之后,字符串的最终形态是什么?
示例:
输入:abbc
输出:ac
s = input()
stack = []
for i in s:
if len(stack) == 0:
stack.append(i)
else:
if stack[-1] == i:
stack.pop()
else: stack.append(i)
if len(stack) == 0:
print(0)
else:
for i in stack:
print(i, end="")
思路:遍历字符串,如果栈空,直接添加;否则,如果栈顶元素与其相等,则出栈,否则添加。
AB6 表达式求值
请写一个整数计算器,支持加减乘三种运算和括号。
示例:
输入:“1+2” 返回值:3
AB7 队列
请你实现一个队列。
操作:
push x:将 𝑥加入队尾,保证 𝑥为 int 型整数。
pop:输出队首,并让队首出队
front:输出队首:队首不出队
class queue:
def __init__(self):
self.items = []
def push(self, item):
self.items.append(int(item))
def pop(self):
return self.items.pop(0)
def front(self):
return self.items[0]
def size(self):
return len(self.items)
q = queue()
num = input()
for _ in range(int(num)):
a = input()
if a.split()[0] == "push":
b = a.split()[1]
q.push(b)
elif a == "pop":
if q.size() == 0:
print("error")
else: print(q.pop())
elif a == "front":
if q.size() == 0:
print("error")
else: print(q.front())
AB8 循环队列
请你实现一个循环队列,该循环队列可利用的空间大小等于𝑛个int型变量的大小。
操作:
push x:将𝑥加入到循环队列尾端。若循环队列已满,输出"full"(不含引号),否则不输出任何内容。保证𝑥为int型整数。
front:输出队首元素,队首不出队。若队列为空,输出"empty"(不含引号)。
pop:输出队首元素,且队首出队。若队列为空,输出"empty"(不含引号)。
class Queue:
def __init__(self):
self.items = []
def push(self, item):
self.items.append(int(item))
def pop(self):
return self.items.pop(0)
def front(self):
return self.items[0]
def size(self):
return len(self.items)
s = input()
size = int(s.split()[0])
num = s.split()[1]
q = Queue()
for _ in range(int(num)):
a = input()
if a.split()[0] == "push":
if q.size() == size:
print("full")
else:
b = a.split()[1]
q.push(b)
elif a == "pop":
if q.size() == 0:
print("empty")
else:
print(q.pop())
elif a == "front":
if q.size() == 0:
print("empty")
else:
print(q.front())
AB9 链表
请你实现一个链表。
操作:
insert x y:将𝑦加入链表,插入在第一个值为𝑥的结点之前。若链表中不存在值为𝑥的结点,则插入在链表末尾。保证𝑥,𝑦为int型整数。
delete x:删除链表中第一个值为𝑥的结点。若不存在值为𝑥的结点,则不删除。
links = []
n = input()
for _ in range(int(n)):
a = input().split()
if a[0] == "insert":
x,y = int(a[1]), int(a[2])
if x in links:
links.insert(links.index(x), y)
else: links.append(y)
elif a[0] == "delete":
x = int(a[1])
if x in links:
links.remove(x)
if len(links) == 0:
print("NULL")
else:
for i in links:
print(i, end=" ")
AB12 删除链表的结点
给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。返回删除后的链表的头节点。
class Solution:
def deleteNode(self , head: ListNode, val: int) -> ListNode:
# write code here
res = ListNode(0)
res.next = head
pre = res
cur = head
while cur:
if cur.val == val:
pre.next = cur.next
break
pre = cur
cur = cur.next
return res.next
AB16 实现二叉树先序、中序、后序遍历
给定一棵二叉树,分别按照二叉树先序,中序和后序打印所有的节点。
class Solution:
def threeOrders(self , root: TreeNode) -> List[List[int]]:
# write code here
res = []
res.append(self.frontOrders(root))
res.append(self.inOrders(root))
res.append(self.endOrders(root))
return res
def frontOrders(self, root):
if root is None: return []
res = []
res.append(root.val)
res += self.frontOrders(root.left)
res += self.frontOrders(root.right)
return res
def inOrders(self, root):
if root is None: return []
res = []
res += self.inOrders(root.left)
res.append(root.val)
res += self.inOrders(root.right)
return res
def endOrders(self, root):
if root is None: return []
res = []
res += self.endOrders(root.left)
res += self.endOrders(root.right)
res.append(root.val)
return res
AB17 从中序与后序遍历序列构造二叉树
给定一个二叉树的中序与后序遍历结果,请你根据两个序列构造符合这两个序列的二叉树。
class Solution:
def buildTree(self , inorder: List[int], postorder: List[int]) -> TreeNode:
# write code here
if not inorder or not postorder: return None
root = TreeNode(postorder[-1])
idx = inorder.index(postorder[-1])
root.left = self.buildTree(inorder[:idx], postorder[:idx])
root.right = self.buildTree(inorder[idx + 1:], postorder[idx : -1])
return root