70:Populating Next Right Pointers in Each Node II

本文探讨了在常数额外空间限制下,如何为二叉树的每个节点填充指向同层下一个节点的指针。提供了两种解决方案:一种是使用层序遍历但不满足空间要求;另一种是在O(1)空间内完成的递归和迭代方法。

题目: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;
                }
        }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值