题目
原题链接
给定一个二叉树
struct Node {
int val;
Node *left;
Node *right;
Node *next;
}
填充它的每个 next
指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next
指针设置为 NULL
。
初始状态下,所有 next
指针都被设置为 NULL
。
进阶:
- 你只能使用常量级额外空间。
- 使用递归解题也符合要求,本题中递归程序占用的栈空间不算做额外的空间复杂度。
示例:
输入:root = [1,2,3,4,5,null,7]
输出:[1,#,2,3,#,4,5,7,#]
解释:给定二叉树如图 A 所示,你的函数应该填充它的每个 next 指针,以指向其下一个右侧节点,如图 B 所示。
提示:
- 树中的节点数小于 6000
-100 <= node.val <= 100
思路
当然,递归函数是一定要定义一个的。(这TM的废话)
对于任意一次递归,只考虑如何设置子节点的 next 属性,分为三种情况:
- 没有子节点:直接返回
- 有一个子节点:
- 将这个子节点的 next 属性设置为同层的下一个节点,即为 root->next 的最左边的一个节点,
- 如果 root->next没有子节点,则考虑 root->nex->next,以此类推 - 有两个节点:左子节点指向右子节点,然后右子节点同第二种情况的做法
注意递归的顺序需要从右到左(为啥呢?其实每次递归都有个前提条件是root->next链表必须是完整的,从右到左递归可以保证这个前提,而从左到右递归不能)
/*
// Definition for a Node.
class Node {
public:
int val;
Node* left;
Node* right;
Node* next;
Node() {}
Node(int _val, Node* _left, Node* _right, Node* _next) {
val = _val;
left = _left;
right = _right;
next = _next;
}
};
*/
class Solution {
public:
Node* connect(Node* root) {
if(root && (root->left || root->right)) {
if(root->left && root->right) root->left->next = root->right;
Node *node = root->right ? root->right : root->left;
Node *head = root->next;
while (head && !(head->left || head->right)){
head = head->next;
}
node->next = head ? (head->left ? head->left : head->right) : nullptr;
connect(root->right);
connect(root->left);
}
return root;
}
};