【问题描述】[中等]
【解答思路】
1. BFS层次遍历思想 (通用)
时间复杂度:O(N) 空间复杂度:O(N)
public Node connect(Node root) {
if (root == null)
return root;
Queue<Node> queue = new LinkedList<>();
queue.add(root);
while (!queue.isEmpty()) {
//每一层的数量
int levelCount = queue.size();
//前一个节点
Node pre = null;
for (int i = 0; i < levelCount; i++) {
//出队
Node node = queue.poll();
//如果pre为空就表示node节点是这一行的第一个,
//没有前一个节点指向他,否则就让前一个节点指向他
if (pre != null) {
pre.next = node;
}
//然后再让当前节点成为前一个节点
pre = node;
//左右子节点如果不为空就入队
if (node.left != null)
queue.add(node.left);
if (node.right != null)
queue.add(node.right);
}
}
return root;
}
2. 链表思想
117
时间复杂度:O(N) 空间复杂度:O(1)
public Node connect(Node root) {
if (root == null)
return root;
//cur我们可以把它看做是每一层的链表
Node cur = root;
while (cur != null) {
//遍历当前层的时候,为了方便操作在下一
//层前面添加一个哑结点(注意这里是访问
//当前层的节点,然后把下一层的节点串起来)
Node dummy = new Node(0);
//pre表示访下一层节点的前一个节点
Node pre = dummy;
//然后开始遍历当前层的链表
while (cur != null) {
if (cur.left != null) {
//如果当前节点的左子节点不为空,就让pre节点
//的next指向他,也就是把它串起来
pre.next = cur.left;
//然后再更新pre
pre = pre.next;
}
//同理参照左子树
if (cur.right != null) {
pre.next = cur.right;
pre = pre.next;
}
//继续访问这一行的下一个节点
cur = cur.next;
}
//把下一层串联成一个链表之后,让他赋值给cur,
//后续继续循环,直到cur为空为止
cur = dummy.next;
}
return root;
}
116
时间复杂度:O(N) 空间复杂度:O(1)
public Node connect(Node root) {
if (root == null)
return root;
//cur我们可以把它看做是每一层的链表
Node cur = root;
while (cur != null) {
//遍历当前层的时候,为了方便操作在下一
//层前面添加一个哑结点(注意这里是访问
//当前层的节点,然后把下一层的节点串起来)
Node dummy = new Node(0);
//pre表示下一层节点的前一个节点
Node pre = dummy;
//然后开始遍历当前层的链表
//因为是完美二叉树,如果有左子节点就一定有右子节点
while (cur != null && cur.left != null) {
//让pre节点的next指向当前节点的左子节点,也就是把它串起来
pre.next = cur.left;
//然后再更新pre
pre = pre.next;
//pre节点的next指向当前节点的右子节点,
pre.next = cur.right;
pre = pre.next;
//继续访问这一行的下一个节点
cur = cur.next;
}
//把下一层串联成一个链表之后,让他赋值给cur,
//后续继续循环,直到cur为空为止
cur = dummy.next;
}
return root;
}
117的思路
时间复杂度:O(N) 空间复杂度:O(1)
public Node connect(Node root) {
if (root == null)
return null;
Node pre = root;
Node cur = null;
while (pre.left != null) {
//遍历当前这一层的结点,然后把他们的下一层连接起来
cur = pre;
//cur不为空,就表示这一层还没遍历完,就继续循环
while (cur != null) {
//让下一层的左子节点指向右子节点
cur.left.next = cur.right;
//如果cur.next不为空,就表示还没遍历到这一层
//最后的那个节点的右子节点,就让前一个结点的右
//子节点指向下一个节点的左子节点
if (cur.next != null)
cur.right.next = cur.next.left;
//然后继续连接下一个节点的 子节点
cur = cur.next;
}
//继续下一层
pre = pre.left;
}
return root;
}
作者:sdwwld
链接:https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node/solution/bfshe-di-gui-zui-hou-liang-chong-ji-bai-liao-100-2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
递归思路
public Node connect(Node root) {
dfs(root, null);
return root;
}
private void dfs(Node curr, Node next) {
if (curr == null)
return;
curr.next = next;
dfs(curr.left, curr.right);
dfs(curr.right, curr.next == null ? null : curr.next.left);
}
作者:sdwwld
链接:https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node/solution/bfshe-di-gui-zui-hou-liang-chong-ji-bai-liao-100-2/
【总结】
1. BFS套路 队列
2.重新加深了对链表的认视 前驱节点是个好东西
3.二叉树的遍历有
前序遍历
中序遍历
后续遍历
深度优先搜索(DFS)
宽度优先搜索(BFS)
转载链接:https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node-ii/solution/bfsjie-jue-zui-hao-de-ji-bai-liao-100de-yong-hu-by/
转载链接:https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node/solution/bfshe-di-gui-zui-hou-liang-chong-ji-bai-liao-100-2/