leetcode114. 二叉树展开为链表
给你二叉树的根结点 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]
算法思路
将当前节点的右子树接到当前节点的左子树的最右边节点上,然后将当前节点的左子树变成当前节点的右子树,并将左子树重置为空。
递归地来处理当前节点右子树。
算法步骤
1.检查当前节点的左子树是否为空。如果为空,直接转向右子树。
2.如果左子树不为空,找到左子树最右边的节点。
3.将当前节点的右子树连接到左子树最右边的节点上。
4.将当前节点的左子树作为新的右子树,并重置左子树为空。
5.递归地对新的右子树执行相同的操作。
下面是详细图解。
如图所示,第一行1、2、3是一次完整处理,1->2将1节点的右子树接到1的左子树的最右节点4的后面,然后2->3将1的左子树变成新的右子树。后续就是递归地处理了。
具体代码
class Solution {
public:
void flatten(TreeNode* root) {
while (root != nullptr) {
// 左子树为 nullptr,直接考虑下一个节点
if (root->left == nullptr) {
root = root->right;
} else {
// 找左子树最右边的节点
TreeNode* pre = root->left;
while (pre->right != nullptr) {
pre = pre->right;
}
// 将原来的右子树接到左子树的最右边节点
pre->right = root->right;
// 将左子树插入到右子树的地方
root->right = rojot->left;
root->left = nullptr;
// 考虑下一个节点
root = root->right;
}
}
}
};
时间复杂度
时间复杂度是 O(n),其中 n 是二叉树中的节点数。
类似题目
leetcode116 | 填充每个节点的下一个右侧指针 |
---|
我也写有详细题解
,可以看看。