题目:Follow up for problem ”Populating Next Right Pointers in Each Node”.
What if the given tree could be any binary tree? Would your previous solution still work?
Note: You may only use constant extra space.
For example, Given the following binary tree,
1
/ \
2 3
/ \ \
4 5 7
After calling your function, the tree should look like:
1 -> NULL
/ \
2 -> 3 -> NULL
/ \ \
4-> 5 -> 7 -> NULL
解析一:我们最先想到的应该是借助于层序遍历,但其要求的空间为 O(log n),不符合题目中对常数空间的要求,不过该方法的代码如下:
//迭代版本,时间复杂度 O(n),空间复杂度 O(log n)
class Solution {
public:
void connect(TreeLinkNode* root) {
queue<TreeLinkNode*> q1, q2;
if (root) q1.push(root)
while (true) {
if (q1.empty()) break;
while (!q1.empty()) {
auto p = q1.front(), q1.pop();
if (!q1.empty())
p -> next = q1.front();
else p -> next = nullptr;
if (p -> left != nullptr) q2.push(p -> left);
if (p -> right != nullptr) q2.push(p -> right);
}
while (!q2.empty())
q1.push(q2.front()), q2.pop();
}
}
};
解析二:常数空间的代码分为递归和迭代两种版本,不过它们的思想是一模一样的,并且此递归为尾递归
下面解法代码的思想及编写参考了网址https://github.com/soulmachine/leetcode#leetcode题解题目
递归代码如下:
// 递归版本,时间复杂度 O(n),空间复杂度 O(1)
class Solution {
public:
void connect(TreeLinkNode* root) {
if (!root) return;
TreeLinkNode dummy{-1};
for (TreeLinkNode *curr = root, *prev = &dummy; curr; curr = curr -> next) {
if (curr -> left != nullptr) {
prev -> next = cur -> left;
prev = prev -> next;
}
if (cur -> right != nullptr) {
prev -> next = curr -> right;
prev = prev -> next;
}
}
connect(dummy.next);
}
};
迭代代码如下:
// 迭代版本,时间复杂度 O(n),空间复杂度 O(1)
class Solution {
public:
void connect(TreeLinkNode* root) {
TreeLinkNode* cur = root;
while (cur) {
TreeLinkNode dummy{-1};
TreeLinkNode* prev = &dummy;
while (cur) {
if (cur -> left) {
prev -> next = cur -> left;
prev = prev -> next;
}
if (cur -> right) {
prev -> next = cur -> right;
prev = prev -> next;
}
cur = cur -> next;
}
cur = dummy.next;
}
}
};