要注意题目给出的条件,其中,使用递归是可以,而使用递归,也是最直观的,且可以假设是一个完美二叉树,因此在处理的时候,可以减少判断逻辑。
先上代码:
public void connect(TreeLinkNode root) {
if (root!=null) {
root.next = null;
method(root.left, root, null);
method(root.right, root, null);
}
}
public void method(TreeLinkNode current, TreeLinkNode parent, TreeLinkNode parentNext) {
if (current==null) return;
// 如果当前节点是左子节点
if (current==parent.left) {
current.next = parent.right;
method(current.left, current, parent.right);
method(current.right, current, parent.right);
}
// 如果是当前节点是右子节点
if (current==parent.right) {
if (parentNext!=null) {
current.next = parentNext.left;
method(current.left, current, parentNext.left);
method(current.right, current, parentNext.left);
} else {
current.next = null;
method(current.left, current, null);
method(current.right, current, null);
}
}
}
存在两种情况,分别如下(示例图片只展示关键部分):
情况一
假设当前节点 current
是左子节点,那么对其处理不依赖于其父节点右兄弟节点 parentNext
,那么,可以直接设置其 next
为其右兄弟节点(题目已经限定为完美二叉树,其右兄弟节点肯定不为空),然后设置下一级的递归。
current.next = parent.right;
method(current.left, current, parent.right);
method(current.right, current, parent.right);
情况二
假设当前节点 current
是右子节点,那么对其处理需要视其父节点的右兄弟节点而定。
当 parentNext!=null
,就表示 parent
不是其所在层最右边的节点,则有
current.next = parentNext.left;
method(current.left, current, parentNext.left);
method(current.right, current, parentNext.left);
否则,parent 则会其所在层的最右边的节点,则有
current.next = null;
method(current.left, current, null);
method(current.right, current, null);
然后还看到的提交记录里面最快的一种实现。
public void connect(TreeLinkNode root) {
if (root == null) {
return;
}
// 判空是为来防止叶子节点的影响
if (root.left != null) {
root.left.next = root.right;
}
// root.right != null 也是为了叶子节点的影响
// 1.如果 root.next==null,则当前 root 节点处于其所在层的最右边,
// 所以其右子节点的 next 即为 null
// 2.如果 root.next!=null,即 root 的右兄弟节点不为空,则其右子节点
// 的 next 指向 root 的右兄弟节点的左子节点
if (root.next != null && root.right != null) {
root.right.next = root.next.left;
}
connect(root.left);
connect(root.right);
}
这里在实现就是前面的简化版本,因为前面传递的 parentNext
即为这里 root.next
,current
直接利用 node.left
和 node.right
得到, 且某些情况下 node.next==null
,符合默认情况同样是 node.next==null
,因此没有再另外处理了。