原题链接:116. Populating Next Right Pointers in Each Node
【思路-Java、Python】
由于题目要求不能申请额外空间,并且已经说明给定的树为完全二叉树。
public class Solution {
public void connect(TreeLinkNode root) {
if (root == null) return;
TreeLinkNode nextLevelFirst = null;
while (root.left != null) { //当前节点的左子树为空的完全二叉树意味着下一层没有节点
nextLevelFirst = root.left;
while (root != null) {
root.left.next = root.right; //连接父节点的左右孩子
root.right.next = root.next==null ? null : root.next.left; //连接堂兄弟的左右节点
root = root.next;
}
root = nextLevelFirst;
}
}
}
14 / 14
test cases passed. Runtime: 0 ms Your runtime beats 81.40% of javasubmissions.
class Solution(object):
def connect(self, root):
"""
:type root: TreeLinkNode
:rtype: nothing
"""
if not root : return
nextLevelFirst = root
while root.left :
nextLevelFirst = root.left
while root :
root.left.next = root.right
if root.next != None: root.right.next = root.next.left
root = root.next
root = nextLevelFirst
14 / 14
test cases passed. Runtime: 101 ms Your runtime beats 35.38% of pythonsubmissions.
【思路2-Java、Python】-递归实现
递归实现空间复杂度肯定是不符合要求的,但是,为了扩展视野,既懂递归实现又懂非递归实现,可以很好地帮助我们理解两者的区别,实际编程中可以游刃有余:
1. 既然非递归寻找下一层的第一个节点需要用到 nextLevelFirst,那么我们同样地在形参中增加一个 nextLevelFirst 参数。
2. 非递归实现的终止条件是 nextLevelFirst 为空,那么递归实现的终止条件也是 nextLevelFirst 为空
3. 非递归的 next 节点为空时,进行下一层的遍历,那么递归实现进行下一层遍历的条件也是 root.next 为空。同时更新 nextLeftFirst 引用
从上面几点,我们可以看到递归和非递归是高度统一的:
public class Solution {
public void connect(TreeLinkNode root) {
if (root != null)
dfs(root, root.left);
}
private void dfs(TreeLinkNode root, TreeLinkNode nextLevelFirst) {
if (nextLevelFirst == null) return;
root.left.next = root.right;
if (root.next == null) {
dfs(nextLevelFirst, nextLevelFirst.left);
} else {
root.right.next = root.next.left;
dfs(root.next, nextLevelFirst);
}
}
}
14 / 14
test cases passed. Runtime: 1 ms Your runtime beats 29.25% of javasubmissions.
class Solution(object):
def connect(self, root):
if not (root and root.left):
return
root.left.next = root.right
if root.next:
root.right.next = root.next.left
map(self.connect, (root.left, root.right))
14 / 14
test cases passed. Runtime: 104 ms Your runtime beats 23.10% of pythonsubmissions.
【思路3-Java】-仅供参考,不推荐
如果没有仔细思考,没有利用到 next 指针,我们可能很快就想到利用队列实现二叉树的层次遍历,但这样与思路1相比不仅造成空间浪费,而且时间复杂度更高:
public class Solution {
public void connect(TreeLinkNode root) {
if (root == null) return;
Queue<TreeLinkNode> queue = new LinkedList<TreeLinkNode>();
queue.add(root);
queue.add(null); //将null加入该层的结尾,作为该层的结束标志
TreeLinkNode temp = root;
while (!queue.isEmpty()) {
if (root != null) { //本层还未遍历完
if (root.left != null) //将左孩子加入队列,作为下一层节点
queue.add(root.left);
if (root.right != null) //将右孩子加入队列,作为下一层节点
queue.add(root.right);
} else { //本层遍历完成,开始遍历下一层
queue.add(null); //加入null作为本层结束的标志
root = queue.poll();
temp = root;
continue;
}
root = queue.poll(); //取出本层的下一个节点
temp.next = root; //设置next指针
temp = root;
}
}
}
14 / 14
test cases passed. Runtime: 8 ms Your runtime beats 2.81% of javasubmissions.