LeetCode 116: 填充每个节点的下一个右侧节点指针 Populating Next Right Pointers in Each Node
题目:
给定一个完美二叉树,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:
You are given a perfect binary tree where all leaves are on the same level, and every parent has two children. The binary tree has the following definition:
struct Node {
int val;
Node *left;
Node *right;
Node *next;
}
填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL
。
Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set to NULL
.
初始状态下,所有 next 指针都被设置为 NULL
。
Initially, all next pointers are set to NULL
.
示例:
![img](https://i-blog.csdnimg.cn/blog_migrate/6411da119389fdefb01d4178cc0922ca.png)
输入:root = [1,2,3,4,5,6,7]
输出:[1,#,2,3,#,4,5,6,7,#]
解释:给定二叉树如图 A 所示,你的函数应该填充它的每个 next 指针,以指向其下一个右侧节点,如图 B 所示。
提示:
你只能使用常量级额外空间。
使用递归解题也符合要求,本题中递归程序占用的栈空间不算做额外的空间复杂度。
Follow up:
You may only use constant extra space.
Recursive approach is fine, you may assume implicit stack space does not count as extra space for this problem.
提示:
树中的节点数小于
4096
-1000 <= node.val <= 1000
Constraints:
The number of nodes in the given tree is less than
4096
.-1000 <= node.val <= 1000
解题思路:
最简单的方法就是层序遍历二叉树,把各个结点的next
指针按要求连起来即可。题目要求不允许占用额外空间,但是递归空间占用不算在内,所以可以递归方法的层序遍历解题,很简单可以参考之前的文章:
这里介绍另一种巧妙的解法:利用已构建的next
指针解题。
核心思路只有两个:
一个结点的左孩子的
next
指针指向该结点的右孩子一个结点的右孩子的
next
指针指向该结点的next
结点的左孩子
即:
node.left.next=node.right;
node.right.next=node.next.left;
剩下的无非就是判断该结点是否为空结点,或值是否为该层结点的最后一个结点,而后进入下一层重复操作。
Java:
class Solution {
public Node connect(Node root) {
if(root == null)
return root;
// 记录每层的最左结点,该层遍历结束后利用最左侧结点进入下一层
Node most_left = root;
Node node = root;
while(most_left.left!=null){// 最左侧结点的下一层只要存在结点,则继续操作
if(node.left != null)
node.left.next=node.right;
if(node.next != null){ // 判断该结点是否为该层的最后一个结点
node.right.next = node.next.left;
node = node.next; // 刷新该结点为 next 结点
}else{
most_left = most_left.left; // 刷新最左侧结点
node = most_left;
}
}
return root;
}
}
Python:
class Solution:
def connect(self, root: 'Node') -> 'Node':
if not root:
return root
# 记录每层的最左结点,该层遍历结束后利用最左侧结点进入下一层
most_left = root
node = root
while most_left.left: # 最左侧结点的下一层只要存在结点,则继续操作
if node.left:
node.left.next = node.right
if node.next: # 判断该结点是否为该层的最后一个结点
node.right.next = node.next.left
node = node.next # 刷新该结点为 next 结点
else:
node = most_left.left # 刷新最左侧结点
most_left = node
return root