LeetCode 116 填充每个节点的下一个右侧节点
Leetcode 116 填充每个节点的下一个右侧节点
将一个完美二叉树中每一个节点中的next指针指向同层右侧相邻节点,没有则指向null
方法1: 层序遍历(O(N)时间复杂度,O(N)空间复杂度)
执行用时:4 ms, 在所有 Java 提交中击败了20.62%的用户
内存消耗:40.2 MB, 在所有 Java 提交中击败了19.29%的用户
class Solution {
//层序遍历,每层内设置next指针执行右边一个节点
public Node connect(Node root) {
if(root==null) {
return root;
}
int currNodesNum = 1, nextNodesNum = 0;
Queue<Node> nodeQueue = new LinkedList<>();
Node peek = null;
nodeQueue.offer(root);
while(!nodeQueue.isEmpty()) {
//取出两个节点
peek = nodeQueue.poll();
currNodesNum--;
peek.next = (currNodesNum==0)?null:nodeQueue.peek();
//添加下层节点
if(peek.left!=null) {
nodeQueue.offer(peek.left);
nextNodesNum++;
}
if(peek.right!=null) {
nodeQueue.offer(peek.right);
nextNodesNum++;
}
//层交替
if(currNodesNum==0) {
currNodesNum = nextNodesNum;
nextNodesNum = 0;
}
}
return root;
}
}
方法2: 利用已有的next指针(O(N)时间复杂度,O(1)空间复杂度)
- 以下代码同样适用于任意(非完美)二叉树
执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
内存消耗:38.8 MB, 在所有 Java 提交中击败了92.16%的用户
class Solution {
public Node connect(Node root) {
if(root==null) {
return null;
}
Node lastLeftMostNode = root;
while(lastLeftMostNode!=null) {
lastLeftMostNode = doOneFloor(lastLeftMostNode);
}
return root;
}
public Node doOneFloor(Node lastLeftMostNode) {
Node currLeftMostNode = null;
for(Node tmpLast=lastLeftMostNode, tmpCurr = currLeftMostNode; tmpLast != null;tmpLast = tmpLast.next) {
//找到下一层左边第一个非null节点
if(tmpCurr==null && !(tmpLast.left==null || tmpLast.right==null)) {
tmpCurr = tmpLast.left!=null? tmpLast.left: tmpLast.right;
currLeftMostNode = tmpCurr;
if(tmpCurr==tmpLast.left && tmpLast.right!=null) {
tmpCurr.next = tmpLast.right;
tmpCurr = tmpCurr.next;
}
}
//开始串联
else if(tmpCurr!=null && !(tmpLast.left==null || tmpLast.right==null)){
tmpCurr.next = tmpLast.left!=null? tmpLast.left: tmpLast.right;
tmpCurr = tmpCurr.next;
if(tmpCurr==tmpLast.left && tmpLast.right!=null) {
tmpCurr.next = tmpLast.right;
tmpCurr = tmpCurr.next;
}
}
}
return currLeftMostNode;
}
}