大家好呀,今天为大家带来的LeetCode的题目是:LeetCode116.填充每个节点的下一个右侧节点指针。属于一道关于二叉树的中等难度的题目。
题目
分析
看完题目后看一下提示内容,一个是只能使用常量级的额外空间,一个是可以使用递归的方法来解决该题目。要是不通过提示的话,看完这个题目的第一反应的解法就是层次遍历,题目要求的是每一层都建立指针,那么我们只需要逐层遍历即可。
通过提示我们知道还有第二种解法就是递归方法。
解法一:层次遍历
这种是最直观的,也是思维难度较低的一种算法,就是从根节点逐层遍历,在遍历的过程中建立指针。
层次遍历是基于广度优先搜索的,与广度优先搜索不同的是,广度优先搜索每次只会取出一个节点,而层次遍历还会把该层元素都获取到,这样我们就可以实现在遍历中修改每个节点的next指针,同时也将其子节点加入到队列中
解法二:递归
对于要建立指针的两个节点来说,只有两种情况:
- 第一种:这两个节点属于同一个父节点,这样我们只需要:node.left.next=node.right
- 第二种:这两个节点属于不同的父节点,这种情况下无法直接连接,所以我们需要从上往下进行建立,利用本层以及建立好的指针来为下一层建立连接。
具体做法就是,从根节点开始遍历(根节点不需要建立连接),然后根据这层的连接关系,开始为下一层建立连接,首先先建立第一种情况的连接,然后利用该层的连接针对第二种情况进行建立连接。
需要注意的是当我们为第N层节点建立next指针时,处于第N-1层。当第N层节点的next指针全部建立完成后,移至第N层,开始建立第N+1层节点的next指针。
代码实现
解法一:层次遍历
public Node connect(Node root) {
if (root == null) {
return root;
}
// 初始化队列同时将第一层节点加入队列中,即根节点
Queue<Node> queue = new LinkedList<Node>();
queue.add(root);
// 外层的 while 循环迭代的是层数
while (!queue.isEmpty()) {
// 记录当前队列大小
int size = queue.size();
// 遍历这一层的所有节点
for (int i = 0; i < size; i++) {
// 从队首取出元素(移除)
Node node = queue.poll();
// 连接,注意最后一个不需要进行连接,所以要有一个判断。
if (i == size - 1) {
node.next = queue.peek();
}
// 将下一层的节点放进去
if (node.left != null) {
queue.add(node.left);
}
if (node.right != null) {
queue.add(node.right);
}
}
}
// 返回根节点
return root;
}
}
解法二:
public Node connect(Node root) {
if (root == null) {
return root;
}
// 从根节点开始
Node leftmost = root;
while (leftmost.left != null) {
// 遍历这一层节点组织成的链表,为下一层的节点更新 next 指针
Node head = leftmost;
while (head != null) {
// 第一种情况,两个需要建立的子节点有共同的父节点
head.left.next = head.right;
// 第二种情况,此时需要借助上一层的指针来进行建立
if (head.next != null) {
head.right.next = head.next.left;
}
// 指针向后移动,即从该层开始往右边进行移动
head = head.next;
}
// 去下一层的最左的节点,由于建立了该层的连接所以只需要从最左节点开始遍历即可
leftmost = leftmost.left;
}
return root;
}
最后
- 如果觉得看完有收获,希望能给我点个赞,这将会是我更新的最大动力,感谢各位的支持
- 欢迎各位关注我的公众号【java冢狐】,专注于java和计算机基础知识,保证让你看完有所收获,不信你打我
- 如果看完有不同的意见或者建议,欢迎多多评论一起交流。感谢各位的支持以及厚爱。