【LeetCode & 剑指offer刷题】树题18:Populating Next Right Pointers in Each Node
【LeetCode & 剑指offer 刷题笔记】目录(持续更新中...)
Populating Next Right Pointers in Each Node
Given a binary tree
struct TreeLinkNode {
TreeLinkNode *left;
TreeLinkNode *right;
TreeLinkNode *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
.
Note:
-
You may only use constant extra space.
-
Recursive approach is fine, implicit stack space does not count as extra space for this problem.
-
You may assume that it is a perfect binary tree (ie, all leaves are at the same level, and every parent has two children).
Example:
Given the following perfect binary tree,
1
/ \
2 3
/ \ / \
4 5 6 7
After calling your function, the tree should look like:
1 -> NULL
/ \
2 -> 3 -> NULL
/ \ / \
4->5->6->7 -> NULL
C++
/**
* Definition for binary tree with next pointer.
* struct TreeLinkNode {
* int val;
* TreeLinkNode *left, *right, *next;
* TreeLinkNode(int x) : val(x), left(NULL), right(NULL), next(NULL) {}
* };
*/
/*
方法一:递归法
Recursion, more than constant space
*/
class
Solution
{
public
:
void
connect
(
TreeLinkNode
*
root
)
{
if
(!
root
)
return
;
//
对根结点的左右子结点进行连接
if
(
root
->
left
)
root
->
left
->
next
=
root
->
right
;
//
连接左结点和右结点
if
(
root
->
right
)
root
->
right
->
next
=
root
->
next
?
root
->
next
->
left
:
nullptr
;
//
连接右结点与根结点右边结点的左结点
//
对左右子树递归连接
connect
(
root
->
left
);
connect
(
root
->
right
);
}
};
/*
掌握
方法二:迭代法
常数空间
*/
class
Solution
{
public
:
void
connect
(
TreeLinkNode
*
root
)
{
if
(!
root
)
return
;
//start
标记每一层的起始节点,
cur
用来遍历该层的节点
TreeLinkNode
*
start
=
root
,
*
cur
=
nullptr
;
while
(
start
->
left
)
//
需要对下层处理,故要判断
start->left
{
cur
=
start
;
while
(
cur
)
//
每次连接下一层的
next
指针
{
//
对根结点的左右子结点进行连接
if
(
cur
->
left
)
cur
->
left
->
next
=
cur
->
right
;
//连接左结点和右结点
if
(
cur
->
right
)
cur
->
right
->
next
=
cur
->
next
?
cur
->
next
->
left
:
nullptr
;
//连接右结点与根结点右边结点的左结点
cur
=
cur
->
next
;
//
该层的
next
指针已经由上一次的迭代处理好
}
start
=
start
->
left
;
//
下一层的起始结点
}
}
};
//方法三:利用level-order中的递归遍历思想,功能实现了,但是用到了cache,空间复杂度为O(num of levels),不符合题目常数空间的要求(该方法不好!!)
class
Solution
{
public
:
void
connect
(
TreeLinkNode
*
root
)
{
vector
<
TreeLinkNode
*>
cache
;
//用于存储每层上一节点的指针
traverse
(
root
,
1
,
cache
);
}
void
traverse
(
TreeLinkNode
*
root
,
int
level
,
vector
<
TreeLinkNode
*>&
cache
)
{
if
(
root
==
nullptr
)
return
;
//递归的出口
if
(
cache
.
size
()
<
level
)
cache
.
push_back
(
nullptr
);
//初始时存空指针
root
->
next
=
cache
[
level
-
1
];
cache
[
level
-
1
]
=
root
;
traverse
(
root
->
right
,
level
+
1
,
cache
);
//level-order按每层从右往左遍历
traverse
(
root
->
left
,
level
+
1
,
cache
);
}
};