算法笔记-从二叉树原地构建链表

54 阅读1分钟

给你二叉树的根结点 root ,请你将它展开为一个单链表:

  • 展开后的单链表应该同样使用 TreeNode ,其中 right 子指针指向链表中下一个结点,而左子指针始终为 null 。
  • 展开后的单链表应该与二叉树 先序遍历 顺序相同。

题目说是前序遍历的链表, x

空间O(1)法(假)

由于不能一边构建一边遍历,因此只能后序遍历:遍历完,回溯栈帧时修改节点才能保持二叉树遍历的顺序。

找规律

  1. 终止遍历的边界:叶子节点
  2. 右子树挂在左子树后:找到左子树链表的最后一个节点,挂载右子树链表,否则直接挂右子树链表。

空间占用大小 栈帧占用空间,那么递归实际空间占用是O(n)

class Solution {
public:
    TreeNode* buildLink(TreeNode* node) {
        if (!node) { return nullptr; }
            TreeNode* rightLink = buildLink(node->right);
            TreeNode* leftLink = buildLink(node->left);
            if(leftLink) {
                TreeNode *pNext = leftLink;
                while( pNext->right ) {
                    pNext = pNext->right;
                }
                pNext->right = rightLink;
            }
            else {
                leftLink = rightLink;
            }
        node->left = nullptr;
        node->right = leftLink;
        return node;
    }
void flatten(TreeNode* root) {
    if (!root) { return; }
        buildLink(root);
    }
};