层序遍历是非常常用的模板。它的思想和广度优先搜索类似。用到了栈,在leetcode中,有很多变种。
def level_order(root):
levels = []
if not root:
return []
cur_level = list()
cur_level.append(root)
while len(cur_level) > 0:
cur_eles = []
next_level = []
for node in cur_level:
cur_eles.append(node.val)
if node.left:
next_level.append(node.left)
if node.right:
next_level.append(node.right)
levels.append(cur_eles)
cur_level = next_level
return levels
变种1. 117. 填充每个节点的下一个右侧节点指针 II
采用层序遍历的思想,但空间复杂度仅为O(h)。其中h为树的高度。最坏时为O(n).可以优化不建立pre节点,空间复杂度为O(1).
class Solution:
def connect(self, root: 'Node') -> 'Node':
level_head = root
while level_head:
pre = next_head = Node(0)
cur = level_head
while cur:
if cur.left:
pre.next = cur.left
pre = pre.next
if cur.right:
pre.next = cur.right
pre = pre.next
cur = cur.next
level_head = next_head.next
return root
若是满二叉树,则还有一种拉链法。实现特别优雅。基本思想是将二叉树分为左右两半,先将左右两半中最靠近的节点相连。采用先序遍历。
def connect(self, root: 'Node') -> 'Node':
# 拉链法解法、很优雅
if not root:
return None
left = root.left
right = root.right
while left:
left.next = right
left = left.right
right = right.left
self.connect(root.left)
self.connect(root.right)
return root