题目:
Given a binary tree
struct Node {
int val;
Node *left;
Node *right;
Node *next;
}
Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set to NULL.
Initially, all next pointers are set to NULL.
Follow up:
- You may only use constant extra space.
- Recursive approach is fine, you may assume implicit stack space does not count as extra space for this problem.
Example 1:
Input: root = [1,2,3,4,5,null,7] Output: [1,#,2,3,#,4,5,7,#] Explanation: Given the above binary tree (Figure A), your function should populate each next pointer to point to its next right node, just like in Figure B. The serialized output is in level order as connected by the next pointers, with '#' signifying the end of each level.
Constraints:
- The number of nodes in the given tree is less than
6000. -100 <= node.val <= 100
思路:
这道相当于116. Populating Next Right Pointers in Each Node的变种。给的是常规binary tree,即非叶子节点可能没有左子或右子。同样的,如果用常规BFS,以queue为容器,可以和116一模一样的做法,应该不用改代码,这里讨论no extra space的做法。难点在于找到当前节点右子的next,因为如果有左子,则左子的next为当前节点的右子即可。用一个指针temp来记录当前节点的next。然后开始寻找。当temp存在的时候,三种情况:temp有左子,那么左子可以为当前节点的next,如果temp没左子有右子,那么右子可以当作next,如果没左子没右子是个叶子节点,这时候依然要寻找temp的next,而不能直接设temp为NULL,因为很可能是某一层中间几个node没有子,但是右边有。比如某一层是4->5->6->NULL,4有左子7,5无子,6有右子8,则下一层应该是7->8->NULL。按照上面的算法,如果我们当前在4,4的next是5,也是temp,5无子,那么就应该继续去寻找5的next,6;而不是把temp设成NULL,因为可能6有子,可以成为4的子的next。这里为什么说是4的子呢,因为当4只有左,没有右时,temp(通过算法寻找到6以后发现无左有右,则temp应该为8)就是4的左子的next,而4无右子就不安排了,本身就是NULL即可。找到正确的temp以后,要注意一个点是如果有右子先递归右子,再递归左子,因为如下图所示,如果先左,当到7的时候,右边还没被递归,9的next还是NULL而不是1,因此7的next变成NULL而会漏了两个8。这个地方如果先左再右会报错,要注意。
2
/ \
1 3
/ \ / \
0 7 9 1
/ / \ / \
2 1 0 8 8
/
7
代码:
/*
// Definition for a Node.
class Node {
public:
int val;
Node* left;
Node* right;
Node* next;
Node() : val(0), left(NULL), right(NULL), next(NULL) {}
Node(int _val) : val(_val), left(NULL), right(NULL), next(NULL) {}
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)
return root;
Node* temp=root->next;
//for node 1, if there is next node 2 for same level, left/right of 2 will be the next for the right of node 1.
while(temp)
{
if(temp->left) //if has left, we use left
{
temp=temp->left;
break;
}
else if(temp->right)
{
temp=temp->right;
break;
}
else
temp=temp->next;
//if no child for this node:
//1. this is last node for this level, next will be null
//2. go to next to check if there is child for next level
}
if(root->right)
root->right->next=temp;
if(root->left)
root->left->next=root->right?root->right:temp;
//if node 1 has left and right, right should be the next of left, else next of left should be the temp, which is the same level node/null
//connect right first
connect(root->right);
connect(root->left);
return root;
}
};