二叉树展开为链表
题目
给定一个二叉树,原地将它展开为链表。
例如,给定二叉树
1
/ \
2 5
/ \ \
3 4 6
将其展开为:
1
\
2
\
3
\
4
\
5
\
6
这道题,阿里巴巴、字节跳动、华为、微软在面试的时候都问过。
解题
思路
就是利用树的左右节点成为线性的结构,1的左节点为空,右节点为2,2的左节点为空,右节点为3…
定眼一看,结果就是一个前序遍历,第一想法是按照前序遍历的顺序,把第二个元素挂到第一个元素右节点上面…但是这样,你会发现原有的结构被你破坏了,递归下去就不是前序遍历了。
方法一
很low但是很好想,前序遍历,按照前序遍历的顺序把节点存到数组里面,然后挨个取出来改结构,你所有节点的引用我都有了,我就不怕你结构变了我找不到了。
方法二
从前往后会改变结构,好,我从后往前不就得了,前悬遍历是
- 打印当前节点
- 左节点递归
- 右节点递归
我们倒着来,后序遍历
- 右节点递归
- 左节点递归
- 打印当前节点
这样做的好处是,你是最后面的,我改了你的结构也不影响前面的。定以一个变量记录当前的节点,阿然后把下一个节点的右节点设置成记录的节点,,,以此类推。
代码
方法一
class Solution {
List<TreeNode> list = new ArrayList<>();
public void flatten(TreeNode root) {
getList(root);
for (int i = 0; i < list.size(); i++) {
if (i == 0 && i + 1 < list.size()) {
list.get(i).right = list.get(i + 1);
list.get(i).left = null;
} else if (i == list.size() - 1) {
list.get(i).left = null;
list.get(i).right = null;
} else {
list.get(i).left = null;
list.get(i).right = list.get(i + 1);
}
}
}
private void getList(TreeNode root) {
if (root != null) {
list.add(root);
getList(root.left);
getList(root.right);
}
}
}
方法二
class Solution {
TreeNode pre = null;
public void flatten(TreeNode root) {
if (root != null) {
flatten(root.right);
flatten(root.left);
if (pre == null) {
pre = root;
} else {
root.left = null;
root.right = pre;
pre = root;
}
}
}
}