Skip to main content

117.填充每个节点的下一个右侧节点指针 II

标签: tree, breadth-first-search, depth-first-search

难度: Medium

通过率: 54.26%

原题链接: https://leetcode.com/problems/populating-next-right-pointers-in-each-node-ii/description/

题目描述​

给定一个二叉树,将每个节点的 next 指针填充到其下一个右侧节点。如果没有下一个右侧节点,则将 next 指针设置为 NULL。最初所有的 next 指针都被设置为 NULL。

解题思路​

为了填充每个节点的下一个右侧节点的指针,我们可以使用层次遍历的方法,这种方法可以用广度优先搜索实现。

  1. 初始化一个变量 current 指向根节点。我们需要一个外层循环遍历每一层节点,并在内层循环中遍历当前层的每个节点。
  2. 对于每层的节点,通过 next 指针找到所有节点,使用一个额外的指针 dummy 作为新的下一层的起始。
  3. 遍历当前层使用 next 指针。在遍历过程中,链接下一层的所有节点。即,把当前节点的左子节点和右子节点用 next 链接起来。
  4. 调整 current 指向下一层的起始节点,继续进行步骤2和3。

伪代码如下:

  • 初始化 current 为根节点。
  • 循环直到 current 为 NULL:
    • 初始化 dummy 节点作为连结节点。
    • 使用变量 tail 指向 dummy。
    • 遍历 current 所有的节点:
      • 如果节点有左子节点,让 tail.next = current.left 然后移动 tail。
      • 如果节点有右子节点,让 tail.next = current.right 然后移动 tail。
    • 更新 current 指向 dummy.next(这一层的开始节点)。

代码实现​

class Solution:  
def connect(self, root: 'Optional[Node]') -> 'Optional[Node]':
if not root:
return root

# 从根开始,逐层连接
current = root
while current:
dummy = Node(0) # 用dummy来起头
tail = dummy
# 遍历当前层
while current:
if current.left:
tail.next = current.left # 链接左子节点
tail = tail.next # 继续移动 tail
if current.right:
tail.next = current.right # 链接右子节点
tail = tail.next # 继续移动 tail
current = current.next # 移动至下一个节点
# 移动至下一层,dummy.next是新的起点
current = dummy.next
return root

复杂度分析​

时间复杂度 O(n)O(n),其中 nn 是树中节点的数量,因为每个节点都被访问一次。
空间复杂度 O(1)O(1),不计算递归栈空间,额外的空间使用是常数级的。