天机阁

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

2022-07-08 · 2 min read
LeetCode

给定一个 完美二叉树 ,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:

struct Node {
  int val;
  Node *left;
  Node *right;
  Node *next;
}

填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。

初始状态下,所有 next 指针都被设置为 NULL。

难度:🌟🌟🌟

示例 1:

输入:root = [1,2,3,4,5,6,7]
输出:[1,#,2,3,#,4,5,6,7,#]
解释:给定二叉树如图 A 所示,你的函数应该填充它的每个 next 指针,以指向其下一个右侧节点,如图 B 所示。序列化的输出按层序遍历排列,同一层节点由 next 指针连接,'#' 标志着每一层的结束。

示例 2:

输入:root = []
输出:[]

提示:

  • 树中节点的数量在 [0, 212 - 1] 范围内
  • -1000 <= node.val <= 1000

题解

这题和层序遍历过程很像,可以理解为在层序遍历的同时完成对节点右侧指针的赋值。
使用到队列数据结构。

代码实现

/**
 * Definition for a Node.
 * type Node struct {
 *     Val int
 *     Left *Node
 *     Right *Node
 *     Next *Node
 * }
 */

func connect(root *Node) *Node {
	if root == nil {
		return nil
	}
	p := root
	queue := newNodeQueue()
	queue.offer(p)
	for !queue.isEmpty() {
		sz := queue.len()
		var q *Node // 用来完成指向 next 节点的操作
		for sz > 0 {
			p = queue.pop()
			if p.Left != nil {
				queue.offer(p.Left)
			}
			if p.Right != nil {
				queue.offer(p.Right)
			}
			if q == nil {
				q = p
			} else {
				q.Next = p
				q = p
			}
			sz--
		}
	}
	return root
}

type nodeQueue struct {
	data []*Node
}

func newNodeQueue() *nodeQueue {
	return &nodeQueue{}
}

func (q *nodeQueue) offer(elem *Node) {
	q.data = append(q.data, elem)
}

func (q *nodeQueue) pop() *Node {
	res := q.data[0]
	q.data = q.data[1:]
	return res
}

func (q *nodeQueue) len() int {
	return len(q.data)
}

func (q *nodeQueue) isEmpty() bool {
	return q.len() == 0
}