一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第10天,点击查看活动详情。
周一,戴上我的痛苦面具
二叉树展开为链表
该题出自力扣的114题 —— 二叉树展开为链表【中等】
审题
给你二叉树的根结点 root ,请你将它展开为一个单链表:
展开后的单链表应该同样使用 TreeNode ,其中 right 子指针指向链表中下一个结点,而左子指针始终为 null 。
展开后的单链表应该与二叉树 先序遍历 顺序相同。
- 该题的题意也十分简单,就是给出一个二叉树,需要把它展开成为一个链表
- 首先,展开成为链表,需要使这个二叉树成为线性,也就是全部整合到右节点
- 第一步,把整个右子树移动到左子树的最右节点
- 第二步,再把整个左子树移动到右子树
- 左子树置空
- 重复一二步
- 利用代码去实现该逻辑也好说
- while,当前节点不为空时循环
- 重复上述步骤即可
- 除此以外还可以利用递归的方式,而且做到空间复杂度为O(1),也就是不额外开辟新的空间去装载二叉树,毕竟开辟空间的话,方法很多,枚举存储节点+重新排序等
- 更多说的是直接在原来的节点上改变指向,空间复杂度并没有要求。
- 如果利用先序遍历的话,直接把当前节点指向上一节点的右节点,虽然看起来能行得通,但是实际操作会导致上一节点的原右节点丢失
- 所以可以利用逆后序方法
- 后序遍历:左右中
- 逆后序遍历:右左中
- 每遍历一个节点,就把当前节点的右节点指向上一节点即可
编码
- 非递归实现
class Solution {
private TreeNode pre = null;
public void flatten(TreeNode root) {
while (root != null){
if (root.left == null){
root = root.right;
}else {
TreeNode pre = root.left;
while (pre.right != null){
pre = pre.right;
}
pre.right = root.right;
root.right = root.left;
root.left = null;
root = root.right;
}
}
}
}
- 递归实现
class Solution {
private TreeNode pre = null;
public void flatten(TreeNode root) {
if (root == null)
return;
flatten(root.right);
flatten(root.left);
root.right = pre;
root.left = null;
pre = root;
}
}