填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL 。 初始状态下,所有 next 指针都被设置为 NULL 。
输入输出示例
示例 1: 输入:root = [1,2,3,4,5,null,7] 输出:[1,#,2,3,#,4,5,7,#] 解释:给定二叉树如图 A 所示,你的函数应该填充它的每个 next 指针,以指向其下一个右侧节点,如图 B 所示。序列化输出按层序遍历顺序(由 next 指针连接),’#’ 表示每层的末尾。
示例 2: 输入:root = [] 输出:[]
提示:
树中的节点数在范围 [0, 6000] 内
-100 <= Node.val <= 100
题目分析
方法一:层序遍历
由图示可知,每一个节点的 next 指的就是和节点处于同一层的下一个节点,我们很容易想到二叉树的层序遍历。二叉树常规的层序遍历方式是使用一个 Queue,首先把二叉树的根节点入队,然后当队列数目不为空时,将队头元素出队,然后将出队元素的左右孩子入队(如果存在的话),直到 Queue 数目为0结束循环。 但依照题意,我们想要的是将某一层的节点全部相连,而普通层序遍历时,Queue 中的元素某一时刻并不一定是同一层的,所以我们可以在层序遍历的基础上稍微进行一些修改,找到属于同一层的所有节点。具体的方式就是在一次 while 循环开启的时候,记录下当前 Queue 中的数目元素 n,然后通过 for 循环进行 n 次出队操作,这样就能保证每一次循环出队列的元素都是同一层的,while 结束后的 Queue 元素都是下一层的。
方法二:使用已建立的 next 指针
方法一使用了层序遍历,需要额外的空间。由于必须遍历所有节点,所以无法降低时间复杂度,但可以考虑如何降低空间复杂度。我们由题意可以知道,当我们遍历某一层节点时,由于我们已知每一个节点的 left 和 right,所以其实对于下一层的构造,我们也可以确定。对于每一层,只要知道最左边的节点,就可以遍历该层了。所以从根节点开始,我们可以建立下一层的 next,然后遍历下一层,再建立下下层的 next,以此类推,就不需要使用额外空间了。
/* // Definition for a Node. public class Node { public int val; public Node left; public Node right; public Node next; public Node() {} public Node(int _val) { val = _val; } public Node(int _val, Node _left, Node _right, Node _next) { val = _val; left = _left; right = _right; next = _next; } } */
publicclassSolution { public Node Connect(Node root) { if(root == null) { returnnull; } Queue<Node> queue = new Queue<Node>(); Node last = null; //last代表上一次访问的节点 queue.Enqueue(root); while(queue.Count > 0) { last = null; //每一层和上一层无需串联,对于每一层的循环,需要把last置空 int n = queue.Count; //n不能在循环里获取,因为count数目会发生变化 for(int i = 1; i <= n; i++) { Node temp = queue.Dequeue(); if(temp.left != null) { queue.Enqueue(temp.left); } if(temp.right != null) { queue.Enqueue(temp.right); } //如果当前节点不是首节点,那么就将当前节点作为上一次节点的next if(i != 1) { last.next = temp; } last = temp; //更新last节点 } } return root; } }
/* // Definition for a Node. public class Node { public int val; public Node left; public Node right; public Node next; public Node() {} public Node(int _val) { val = _val; } public Node(int _val, Node _left, Node _right, Node _next) { val = _val; left = _left; right = _right; next = _next; } } */