一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第14天,点击查看活动详情。
一、题目
leetcode 二叉树展开为链表
给你二叉树的根结点 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
二、题解
需要将二叉树转为一个二叉树形态的单链表,并且前序遍历的结果都要相同。
方法一 首先前序遍历的访问顺序先是根节点,然后是左节点,最后是右节点。既然都要求前序遍历的结果得一致,那么我们就可以用前序遍历来构造。可以先使用前序遍历获取原二叉树的所有节点,然后得到的是一个前序遍历顺序的节点集合,然后我们在顺序遍历这个节点集合来构造单链表树,左节点都默认为空,然后右节点就是当前遍历的节点。
方法二 如果对于根节点为1,左节点为2,右节点为3的一个二叉树,如果要变为单链表,那么首先需要将左节点移到根节点的右节点上,然后再吧原本的右节点移到现在的右节点的右节点上,这样可以应用到每个子树上。所以整体看起来就是先将左子树如果左子树不为空的话,然后再把右子树也变为一个连表,最后把右子树的链表移到左子树的链表的右节点上。
三、代码
方法一 Java代码
class Solution {
List<TreeNode> treeList = new ArrayList<TreeNode>();
public void flatten(TreeNode root) {
getTreeList(root);
int size = treeList.size();
for (int i = 1; i < size; i++) {
TreeNode node = treeList.get(i - 1);
node.left = null;
node.right = treeList.get(i);
}
}
public void getTreeList(TreeNode tree) {
if (tree == null) {
return;
}
treeList.add(tree);
getTreeList(tree.left);
getTreeList(tree.right);
}
}
时间复杂度:O(n),需要一次前序遍历二叉树获取节点集合,一次遍历节点集合构造单链表。
空间复杂度:O(n),需要节点集合存储前序遍历的结果已经递归栈空间。
方法二 Java代码
class Solution {
public void flatten(TreeNode root) {
if (root == null) {
return;
}
flatten(root.left);
flatten(root.right);
TreeNode temp = root.right;
root.right = root.left;
root.left = null;
while (root.right != null) {
root = root.right;
}
root.right = temp;
}
}
时间复杂度:O(n),需要遍历节点已经递归栈空间。
空间复杂度:O(1),只需常数的空间。