题目:
难度:Middle
相关话题:树
、深度优先搜索
给定一个二叉树
struct Node {
int val;
Node *left;
Node *right;
Node *next;
}
填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL
。
初始状态下,所有next 指针都被设置为 NULL
。
示例:
输入:{"$id":"1","left":{"$id":"2","left":{"$id":"3","left":null,"next":null,"right":null,"val":4},"next":null,"right":{"$id":"4","left":null,"next":null,"right":null,"val":5},"val":2},"next":null,"right":{"$id":"5","left":null,"next":null,"right":{"$id":"6","left":null,"next":null,"right":null,"val":7},"val":3},"val":1}
输出:{"$id":"1","left":{"$id":"2","left":{"$id":"3","left":null,"next":{"$id":"4","left":null,"next":{"$id":"5","left":null,"next":null,"right":null,"val":7},"right":null,"val":5},"right":null,"val":4},"next":{"$id":"6","left":null,"next":null,"right":{"$ref":"5"},"val":3},"right":{"$ref":"4"},"val":2},"next":null,"right":{"$ref":"6"},"val":1}
解释:给定二叉树如图 A 所示,你的函数应该填充它的每个 next 指针,以指向其下一个右侧节点,如图 B 所示。
提示:
思路:
对于每个root
,通过root.next
来不断定义它的子树的next
,直到root==null
,并且通过变量head
保存当前root
的第一个子树(左优先),当root==null
的时候,设置root=head
,从而跳转到它的第一个子树,继续定义这个子树的子树的next
。
var connect = function(root) {
if(!root)return null
let cur=root,
pre=null,
head=null
while(cur!=null){
while(cur!=null){
if(cur.left){
if(pre)pre.next=cur.left
if(!head)head=cur.left
pre=cur.left
}
if(cur.right){
if(!head)head=cur.right
if(pre)pre.next=cur.right
pre=cur.right
}
cur=cur.next
}
cur=head
head=null
pre=null
}
return root
};
思想和BFS
差不多,对于当前root
,通过root.next
,定义它的子树的next
,注意的是,在递归的时候,需要先递归root.right
,这时因为不像BFS
是一层一层遍历,DFS
是先递归到最底端,然后再返回,而findNext
是找出节点的最左的子节点;
如果先root.left
,那么最底端一些节点就无法通过next
跳转到它的右侧的节点,因为findNext
可能找到了最左的子节点,但没有找到更右边的子节点,因此右边的一些节点可能是还未被连接的。
例如:这里由于5
和6
无法相连,导致7
和8
无法相连。
1 -> 2
/ \ / \
3 -> 4 ->5 6
/ \
7 8
因此,先递归root.right
,确保右边都已经连接完毕,再执行root.left
。
/**
* @来源: Javascript中文网 - 前端进阶资源教程 https://www.javascriptc.com/
* @介绍:一个致力于帮助开发者用代码改变世界为使命的平台,每天都可以在这里找到技术世界的头条内容
* // Definition for a Node.
* function Node(val,left,right,next) {
* this.val = val;
* this.left = left;
* this.right = right;
* this.next = next;
* };
*/
/**
* @param {Node} root
* @return {Node}
*/
var connect = function(root) {
if(!root)return null
// BFS
// let cur=root,
// pre=null,
// head=null
// while(cur!=null){
// while(cur!=null){
// if(cur.left){
// if(pre)pre.next=cur.left
// if(!head)head=cur.left
// pre=cur.left
// }
// if(cur.right){
// if(!head)head=cur.right
// if(pre)pre.next=cur.right
// pre=cur.right
// }
// cur=cur.next
// }
// cur=head
// head=null
// pre=null
// }
// return root
// DFS
makeConnect(root)
return root
function findNext(node){
if(!node)return null
if(node.left)return node.left
if(node.right)return node.right
return findNext(node.next)
}
function makeConnect(node){
if(!node)return
if(node.left && node.right){
node.left.next=node.right
node.right.next=findNext(node.next)
}else if(node.left){
node.left.next=findNext(node.next)
}else if(node.right){
node.right.next=findNext(node.next)
}
makeConnect(node.right)
makeConnect(node.left)
}
};