Hot100-Day58-T114二叉树展开为链表

0 阅读2分钟

Day58[26/3/28]T114二叉树展开为链表

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

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

示例 1:

输入:root = [1,2,5,3,4,null,6]
输出:[1,null,2,null,3,null,4,null,5,null,6]

示例 2:

输入:root = []
输出:[]

示例 3:

输入:root = [0]
输出:[0]

提示:

  • 树中结点数在范围 [0, 2000]
  • -100 <= Node.val <= 100

进阶:你可以使用原地算法(O(1) 额外空间)展开这棵树吗?

解题思路

迭代思路(最容易理解):

  1. 如果当前节点有左孩子:
  2. 找到左孩子的最右端节点。
  3. 将当前节点的原右子树,挂在这个最右端节点后面。
  4. 将当前节点的左孩子变成右孩子(左孩子置空)。
  5. 当前节点移向右孩子,重复上述过程。

示例,节点 1 为例

    1
   / \
  2   5
 / \   \
3   4   6
        1
       / \
      2   5   <-- 5 要挪走
     / \   \
    3   4   6
          ^
          |-- 找到左子树最右节点 4
    把 2 这一支移到右边,清空左边
        1
         \
          2
         / \
        3   4
             \
              5
               \
                6

Code

#include <iostream>
#include <algorithm>

using namespace std;

struct TreeNode
{
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode() : val(0), left(nullptr), right(nullptr) {}
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
    TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
};

class Solution
{
public:
    void flatten(TreeNode *root)
    {
        // 左孩子的最右,右孩子
        TreeNode *leftRightChild = nullptr;
        TreeNode *rightChild = nullptr;
        while (root != nullptr)
        {
            if (root->left)
            {
                // 找左子树的最右节点
                leftRightChild = root->left;
                while (leftRightChild->right)
                {
                    leftRightChild = leftRightChild->right;
                }

                // 存一下右子树
                rightChild = root->right;

                // 左子树替换原来的右子树
                root->right = root->left;
                root->left = nullptr;

                // 左子树的最右侧端点连接上右子树
                leftRightChild->right = rightChild;
            }

            root = root->right;
        }
    }
};

auto main() -> int
{
    cout << "Hello World!" << endl;
}