本文已参与「新人创作礼」活动,一起开启掘金创作之路。
题目
给你二叉树的根结点 root ,请你将它展开为一个单链表:
- 展开后的单链表应该同样使用 TreeNode ,其中 right 子指针指向链表中下一个结点,而左子指针始终为 null 。
- 展开后的单链表应该与二叉树 先序遍历 顺序相同。
输入: root = [1,2,5,3,4,null,6]
输出: [1,null,2,null,3,null,4,null,5,null,6]
题目解析
思路一
我们首先把左子树和右子树都展开为单链表,然后在后序位置把左子树挪到右子树的位置去,右子树再连接到新的最右边的节点下就可以了
/**
* @param {TreeNode} root
* @return {void} Do not return anything, modify root in-place instead.
*/
var flatten = function(root) {
if (root === null) return null;
// 先把左右子树都展开成单链表
flatten(root.left);
flatten(root.right);
// 后序位置操作
// 先保存抻平之后的左子树和右子树
const left = root.left;
const right = root.right;
// 左子树挂到节点右侧
root.left = null;
root.right = left;
// 找到新的最右边的节点p
let p = root;
while (p.right !== null) {
p = p.right;
}
// 把抻平之后到右子树连上去
p.right = right;
};
思路二
我们这里使用递归层层向下找到最左的叶子节点,因为该叶子节点没有子节点,也就无需任何处理就可以满足条件,递归回到其父节点,此处需要做的事情是先找出右子节点,再将其作为左子节点,再将左节点作为右子节点,至此结束,然后将已经被拉直的节点树插入到右节点树中,递归会继续进入及其子节点树就可以了
/**
* @param {TreeNode} root
* @return {void} Do not return anything, modify root in-place instead.
*/
var flatten = function (root) {
function flat(node){
if(!node) return node
flat(node.left)
flat(node.right)
let left = node.left,
right = node.right
node.left = null
node.right = left
let cur = node
while(cur.right){
cur = cur.right
}
cur.right = right
}
flat(root)
}