leetcode-116:填充每个节点的下一个右侧节点指针

简介: leetcode-116:填充每个节点的下一个右侧节点指针

题目

题目链接

给定一个 完美二叉树 ,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:

struct Node {
  int val;
  Node *left;
  Node *right;
  Node *next;
}

填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。

进阶:

  • 你只能使用常量级额外空间。
  • 使用递归解题也符合要求,本题中递归程序占用的栈空间不算做额外的空间复杂度。

示例:

输入:root = [1,2,3,4,5,6,7]
输出:[1,#,2,3,#,4,5,6,7,#]
解释:给定二叉树如图 A 所示,你的函数应该填充它的每个 next 指针,以指向其下一个右侧节点,如图 B 所示。序列化的输出按层序遍历排列,同一层节点由 next 指针连接,'#' 标志着每一层的结束。

解题

方法一:层序遍历(空间复杂度为O(n))

利用层序遍历,每层的第一个节点,指向第二个,第二个指向第三个,最后一个节点,指向None。用i来控制到第几个节点了

python写法

"""
# Definition for a Node.
class Node:
    def __init__(self, val: int = 0, left: 'Node' = None, right: 'Node' = None, next: 'Node' = None):
        self.val = val
        self.left = left
        self.right = right
        self.next = next
"""
class Solution:
    def connect(self, root: 'Node') -> 'Node':
        if not root:
            return root
        queue = [root]
        while queue:
            l = len(queue)
            for i in range(l):
                cur = queue.pop(0)
                left,right = cur.left,cur.right
                if i==l-1:
                    cur.next=None
                else:
                    cur.next=queue[0]
                if left:
                    queue.append(left)
                    queue.append(right)        
        return roo

由于,是完全二叉树,每个节点都有一个左子节点和右节点,因此,if left后直接加入左右子节点就行了。节点的next默认为None,但为了清晰思路,还是写了一遍,其实i的时候cur.next=queue[0]更为简洁。

c++写法

class Solution {
public:
    Node* connect(Node* root) {
        if(!root) return {};
        queue<Node*> queue;
        queue.push(root);
        while(!queue.empty()){
            int l=queue.size();
            for(int i=0;i<l;i++){
                Node* cur=queue.front();
                queue.pop();
                if(i!=l-1){
                    cur->next=queue.front();
                }
                if(cur->left){
                    queue.push(cur->left);
                }
                if(cur->right){
                    queue.push(cur->right);
                }
            }
        }
        return root;
    }
};

方法二:另一种迭代方式(空间复杂度为O(1))

题目要求是常量的辅助空间,所以第一种解法并不符合要求,下面来看下 O(1)O(1)空间复杂度的实现细节。

注意,题目说的二叉树是一棵完美二叉树,即每一层的节点都是满的。

仔细看下完成后的串联树,其连接的方式有两种:

第一种 是这两个串联的节点都有一个共同的父节点,通过父节点就可以将这两个子节点串联起来

第二种 是这两个串联的节点的父节点不同,对于这种情况,如果我们能将这一层的上一层串联好。那么可以通过父节点的next找到邻居,完成串联。

root.right.next => root.next.left

这里我们需要保证 root.next 不为空就可以了。

也就是说当我们要串联第 i 层节点时,需要先完成第 i-1 层的节点串联

第一层最多只有一个节点,不需要串联

第二层最多只有两个节点,借助根节点就可以完成串联了

第三层串联时,上一层已经串联完了,所以第三层可以完成串联

同理,可以完成第四层,第五层,第N层的串联

python写法

"""
# Definition for a Node.
class Node:
    def __init__(self, val: int = 0, left: 'Node' = None, right: 'Node' = None, next: 'Node' = None):
        self.val = val
        self.left = left
        self.right = right
        self.next = next
"""
class Solution:
    def connect(self, root: 'Node') -> 'Node':
        if not root:
            return root
        pre = root
        while pre.left:
            tmp = pre
            while tmp:
                tmp.left.next = tmp.right
                if tmp.next:
                    tmp.right.next = tmp.next.left
                tmp = tmp.next
            pre = pre.left
        return root


相关文章
|
1月前
LeetCode第二十四题(两两交换链表中的节点)
这篇文章介绍了LeetCode第24题的解法,即如何通过使用三个指针(preNode, curNode, curNextNode)来两两交换链表中的节点,并提供了详细的代码实现。
17 0
LeetCode第二十四题(两两交换链表中的节点)
|
1月前
Leetcode第十九题(删除链表的倒数第N个节点)
LeetCode第19题要求删除链表的倒数第N个节点,可以通过快慢指针法在一次遍历中实现。
39 0
Leetcode第十九题(删除链表的倒数第N个节点)
|
1月前
【LeetCode 46】450.删除二叉搜索树的节点
【LeetCode 46】450.删除二叉搜索树的节点
12 0
|
3月前
|
算法
LeetCode第24题两两交换链表中的节点
这篇文章介绍了LeetCode第24题"两两交换链表中的节点"的解题方法,通过使用虚拟节点和前驱节点技巧,实现了链表中相邻节点的交换。
LeetCode第24题两两交换链表中的节点
10_填充每个节点的下一个右侧节点指针
10_填充每个节点的下一个右侧节点指针
|
3月前
|
Python
【Leetcode刷题Python】450. 删除二叉搜索树中的节点
LeetCode上538号问题"把二叉搜索树转换为累加树"的Python实现,使用反向中序遍历并记录节点值之和来更新每个节点的新值。
37 4
【Leetcode刷题Python】450. 删除二叉搜索树中的节点
|
3月前
|
Python
【Leetcode刷题Python】剑指 Offer 22. 链表中倒数第k个节点
Leetcode题目"剑指 Offer 22. 链表中倒数第k个节点"的Python解决方案,使用双指针法找到并返回链表中倒数第k个节点。
52 5
|
3月前
|
Python
【Leetcode刷题Python】222. 完全二叉树的节点个数
LeetCode第222题"完全二叉树的节点个数"的Python代码实现,通过递归和深度优先遍历的方法来计算给定完全二叉树的节点总数。
37 5
|
3月前
|
Python
【Leetcode刷题Python】剑指 Offer 18. 删除链表的节点
Leetcode题目"剑指 Offer 18. 删除链表的节点"的Python解决方案,通过使用双指针法找到并删除链表中值为特定数值的节点,然后返回更新后的链表头节点。
41 4
|
3月前
|
Python
【Leetcode刷题Python】138. 复制带随机指针的链表
LeetCode上题目“138. 复制带随机指针的链表”的Python解决方案,包括两种方法:一种是在每个节点后复制一个新节点然后再分离出来形成新链表;另一种是构建一个字典来跟踪原始节点与其副本之间的映射关系,从而处理新链表的构建。
20 1