二叉树展开为链表
给你二叉树的根结点 root ,请你将它展开为一个单链表:
展开后的单链表应该同样使用 TreeNode ,其中 right 子指针指向链表中下一个结点,而左子指针始终为 null 。
展开后的单链表应该与二叉树 先序遍历 顺序相同。
示例 1:
输入:root = [1,2,5,3,4,null,6]
输出:[1,null,2,null,3,null,4,null,5,null,6]
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {void} Do not return anything, modify root in-place instead.
*/
var flatten = function(root) {
// 1.右节点,放到左节点的最右边叶子节点上
// 2.左节点覆盖到右节点
function dfs(node) {
if(!node) return
if(node.left) {
const leftTail = treeRightTail(node.left) // 获取左节点的最右边叶子节点上
leftTail.right = node.right // 最右边叶子节点的右子树挂载上原本的右节点
node.right = node.left // 左节点覆盖到右节点
node.left = null // 删除左子树
}
dfs(node.right) // 节点都移到右节点上了,只需要递归右节点
}
dfs(root)
};
function treeRightTail(node) {
while(node.right) {
node = node.right
}
return node
}
解题思路:
- 由于当前节点的
左子节点
会覆盖右子节点
,所以需要把右子节点
暂存
起来,但是由于使用dfs深度遍历,始终没有想到合适的暂存
方法 - 仔细分析可以知道,
左子节点
的所有节点拼接完之后,才会开始拼接右子节点
。 - 而先序遍历,根左右,当前节点的最右边的
叶子节点
,一定是最后才遍历到的,所以可以把将右子节点
放到左子节点
的最右边叶子节点
的右子树
上,实现暂存
。
方法论
- 解题尽量自己想,短时间想不出就直接看题解照搬,太难就跳过。
- 不追求完美解题,能解就行。
- 每天有空就来上一题,没空就算了,拒绝内耗。