题目
给定一个 完美二叉树 ,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:
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