层序遍历:102. 二叉树的层序遍历
队列实现,que不为空说明还有层需要处理,处理这一层。先把本层结果进res数组,再把下一层(如果有)进队。
from collections import deque
class Solution:
def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
if not root: return []
que = deque([root])
res = []
while que:
res.append([item.val for item in que])
for _ in range(len(que)):
node = que.popleft()
if node.left: que.append(node.left)
if node.right: que.append(node.right)
return res
递归实现,使用辅助函数,跳过!
class Solution:
def levelOrder(self, root: TreeNode) -> List[List[int]]:
result = []
def traverse(node, depth):
if not node:
return
# 如果当前深度还没有对应的列表,创建一个
if len(result) == depth:
result.append([])
# 将当前节点的值添加到对应深度的列表中
result[depth].append(node.val)
# 递归处理左子树和右子树,深度加1
traverse(node.left, depth + 1)
traverse(node.right, depth + 1)
traverse(root, 0)
return result
下面简单记录下其他9个层序遍历题目。
107. 二叉树的层序遍历 II
from collections import deque
class Solution:
def levelOrderBottom(self, root: Optional[TreeNode]) -> List[List[int]]:
if not root:
return []
res = []
que = deque([root])
while que:
res.append([item.val for item in que])
for _ in range(len(que)):
node = que.popleft()
if node.left: que.append(node.left)
if node.right: que.append(node.right)
return res[::-1]
199. 二叉树的右视图
from collections import deque
class Solution:
def rightSideView(self, root: Optional[TreeNode]) -> List[int]:
if not root:
return []
res = []
que = deque([root])
while que:
level_size = len(que)
for _ in range(level_size):
node = que.popleft()
if _ == level_size - 1:
res.append(node.val)
if node.left:
que.append(node.left)
if node.right:
que.append(node.right)
return res
637. 二叉树的层平均值
from collections import deque
class Solution:
def averageOfLevels(self, root: Optional[TreeNode]) -> List[float]:
if not root:
return []
res = []
que = deque([root])
while que:
level_length = len(que)
res.append(sum([item.val for item in que]) / level_length)
for _ in range(level_length):
node = que.popleft()
if node.left: que.append(node.left)
if node.right: que.append(node.right)
return res
429. N 叉树的层序遍历
注意在N叉树的链式存储中,node.children指向的是一个list。
from collections import deque
class Solution:
def levelOrder(self, root: 'Node') -> List[List[int]]:
if not root:
return []
res = []
que = deque([root])
while que:
level_len = len(que)
cur = []
for _ in range(level_len):
node = que.popleft()
cur.append(node.val)
for child in node.children:
que.append(child)
res.append(cur)
return res
515. 在每个树行中找最大值
from collections import deque
class Solution:
def largestValues(self, root: Optional[TreeNode]) -> List[int]:
if not root:
return []
queue = deque([root])
result = []
while queue:
level_size = len(queue)
level_nodes = []
for _ in range(level_size):
node = queue.popleft()
level_nodes.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
result.append(max(level_nodes))
return result
116. 填充每个节点的下一个右侧节点指针
from collections import deque
class Solution:
def connect(self, root: 'Optional[Node]') -> 'Optional[Node]':
if not root:
return root
queue = deque([root])
while queue:
level_size = len(queue)
level_nodes = []
for _ in range(level_size):
node = queue.popleft()
level_nodes.append(node)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
level_nodes.append(None)
for _ in range(level_size):
level_nodes[_].next = level_nodes[_ + 1]
return root
其实这个题不需要层序遍历,因为已经是完美二叉树,直接左孩子连右孩子,右孩子连next的左孩子即可:
class Solution:
def connect(self, root: 'Optional[Node]') -> 'Optional[Node]':
if not root:
return None
leftmost = root
while leftmost.left:
head = leftmost
while head:
head.left.next = head.right
if head.next:
head.right.next = head.next.left
head = head.next
leftmost = leftmost.left
return root
117. 填充每个节点的下一个右侧节点指针 II
看了上一题的题解,优化一下上一题的写法。
from collections import deque
class Solution:
def connect(self, root: 'Node') -> 'Node':
if not root:
return root
que = deque([root])
while que:
level_size = len(que)
for _ in range(level_size):
node = que.popleft()
if _ < level_size - 1:
node.next = que[0]
if node.left: que.append(node.left)
if node.right: que.append(node.right)
return root
104. 二叉树的最大深度
from collections import deque
class Solution:
def maxDepth(self, root: Optional[TreeNode]) -> int:
if not root:
return 0
que = deque([root])
res = 0
while que:
res += 1
level_size = len(que)
for _ in range(level_size):
node = que.popleft()
if node.left: que.append(node.left)
if node.right: que.append(node.right)
return res
111. 二叉树的最小深度
from collections import deque
class Solution:
def minDepth(self, root: Optional[TreeNode]) -> int:
if not root:
return 0
que = deque([root])
res = 0
while que:
res += 1
level_size = len(que)
for _ in range(level_size):
node = que.popleft()
if not node.left and not node.right: return res
if node.left: que.append(node.left)
if node.right: que.append(node.right)
return res
226. 翻转二叉树
*尝试递归实现:
终止条件:节点为空。递推式:交换翻转转好的左右子树。
看了代码随想录的详解,自己还真想半天才发现自己写的是好像什么遍历顺序都不是。。。根本没有想过遍历顺序这个问题。
自己写的递归实际上是从下往上交换的,与后序遍历类似,但是顺序上不一致。
class Solution:
def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
if not root:
return root
root.left, root.right = self.invertTree(root.right), self.invertTree(root.left)
return root
前序遍历:
前序遍历是从上往下交换的,是个尾递归。
class Solution:
def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
if not root:
return root
root.left, root.right = root.right, root.left
root.left = self.invertTree(root.left)
root.right = self.invertTree(root.right)
return root
class Solution:
def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
if not root:
return root
stack = [root]
while stack:
node = stack.pop()
node.left, node.right = node.right, node.left
if node.right: stack.append(node.right)
if node.left: stack.append(node.left)
return root
后序遍历:
递归实现,交换前序遍历的顺序即可:
class Solution:
def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
if not root:
return root
root.left = self.invertTree(root.left)
root.right = self.invertTree(root.right)
root.left, root.right = root.right, root.left
return root
迭代实现:
class Solution:
def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
if not root:
return root
stack = [root]
while stack:
node = stack.pop()
if node.right: stack.append(node.right)
if node.left: stack.append(node.left)
node.left, node.right = node.right, node.left
return root
中序遍历:
中序遍历递归实现时,本想简单地交换两行。但是这样结果是错误的,因为有的交换多进行了一次。
只要把中交换的下一行的递归输入值也交换一下就可以了。
class Solution:
def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
if not root:
return root
root.left = self.invertTree(root.left)
root.left, root.right = root.right, root.left
root.right = self.invertTree(root.left) #这里需要处理一下,因为中间节点已经交换过了,递归下一轮也要换一下,否则会重复
return root
迭代实现:
class Solution:
def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
if not root:
return root
stack = [root]
while stack:
node = stack.pop()
if node.right: stack.append(node.right)
node.left, node.right = node.right, node.left
if node.left: stack.append(node.right)
return root
复习一下迭代统一实现:
class Solution:
def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
if not root:
return root
stack = [root]
while stack:
node = stack.pop()
if node:
if node.right: stack.append(node.right)
stack.append(node)
stack.append(None)
if node.left: stack.append(node.left)
else:
node = stack.pop()
node.left, node.right = node.right, node.left
return root
层序遍历:
class Solution:
def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
if not root:
return root
que = collections.deque([root])
while que:
level_size = len(que)
for _ in range(level_size):
node = que.popleft()
if node.left: que.append(node.left)
if node.right: que.append(node.right)
node.left, node.right = node.right, node.left
return root
101. 对称二叉树
递归实现:
递归最神奇的一点是isMirror最后一行可以不去判断left.val == right=val!想了半天,其实是因为not left or not right or left.val != right.val的逆命题是left and right and left.val == right.val即终止条件已经判断过这俩的值相等了。
class Solution:
def isSymmetric(self, root: Optional[TreeNode]) -> bool:
if not root:
return True
return self.isMirror(root.left,root.right)
def isMirror(self, left, right):
#终止条件:两个都是空或者return False
if not left and not right: return True
elif not left or not right or left.val != right.val: return False
#递归进行判断
return self.isMirror(left.left, right.right) and self.isMirror(left.right, right.left)
迭代实现:
class Solution:
def isSymmetric(self, root: Optional[TreeNode]) -> bool:
if not root:
return True
stack = [root.left,root.right]
while stack:
r = stack.pop()
l = stack.pop()
if not r and not l:
continue
elif (not r and l) or (r and not l) or (r and l and r.val != l.val):
return False
stack.append(l.left)
stack.append(r.right)
stack.append(l.right)
stack.append(r.left)
return True
理解迭代代码的关键还是刚刚所说的not left or not right or left.val != right.val的逆命题是left and right and left.val == right.val
只有满足left和right都存在且相等时,向que或者stack里面继续压下一对值。
这题居然是easy,真难顶
今日总结:
内容好多啊!!有点绕进去了,又好像理解了????