持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第15天,点击查看活动详情
题目
给定一个 完美二叉树 ,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:
struct Node {
int val;
Node *left;
Node *right;
Node *next;
}
填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。
初始状态下,所有 next 指针都被设置为 NULL。
示例 1
输入:root = [1,2,3,4,5,6,7]
输出:[1,#,2,3,#,4,5,6,7,#]
解释:给定二叉树如图 A 所示,你的函数应该填充它的每个 next 指针,以指向其下一个右侧节点,如图 B 所示。序列化的输出按层序遍历排列,同一层节点由 next 指针连接,'#' 标志着每一层的结束。
示例 2
输入:root = []
输出:[]
提示
- 树中节点的数量在 [0, 2^12 - 1] 范围内
- -1000 <= node.val <= 1000
题解
思路
要学会利用题中给的 next 这一个数 注意一个先前条件:初始状态下,所有 next 指针都被设置为 NULL。 这就意味着最右边的 next,是不需要去加的。
所以加 next 的有2种情况:
- 同父节点的 left 和 right 子节点
- 父节点的 right 结点的 next 为异父结点的 left 结点。
所以要判断的有两个东西:
- 当前结点是否为最后一行;(leftmost->left!=NULL)
- 当前父节点是否为最右边的父节点(head->next!=NULL)
关于1判断: 需要创建一个始终为最左边的结点进行层次遍历,因为最左边的结点一定会有next,所以从root开始创建leftmost结点。
关于2判断: 由于leftmost是我们创建的固定在最左边的结点,不能使用于每一层的遍历,所以在每次遍历前可以创建一个head创建一个head=leftmost进行遍历,并使用while语句,只要不是最右就继续遍历while(head->next!=NULL)(最右的结点的next为NULL)
情况1操作: 直接head->left->next=head->right;
情况2操作: 需要在该head结点不是最右结点情况下进行 head->right->next=head->next->left.
代码
/**
* Definition for a Node.
* struct Node {
* int val;
* struct Node *left;
* struct Node *right;
* struct Node *next;
* };
*/
struct Node* connect(struct Node* root) {
if (root==NULL)
return root;
struct Node*leftmost=root;
while(leftmost->left!=NULL) {
struct Node*head=leftmost;
head->left->next=head->right;
while(head->next!=NULL) {
head->right->next=head->next->left;
head=head->next;
head->left->next=head->right;
}
leftmost=leftmost->left;
}
return root;
}
结语
业精于勤,荒于嬉;行成于思,毁于随。