题目:
给定一个二叉树,原地将它展开为一个单链表。
例如,给定二叉树
1
/ \
2 5
/ \ \
3 4 6
将其展开为:
1
\
2
\
3
\
4
\
5
\
6
抛砖引玉
题意
- 将二叉树的所有右节点放到根节点右侧上
- 放置顺序:先右后左即某节点同时存在左右节点时优先将左侧节点追加右侧
- 前序遍历
思路
- 递归展开左侧所有节点依次追加
- 展开的节点本事还包含其自身的子节点,需要重新定义节点的子节点
- left -> null
- right -> 需要追加的下一个右节点
/**
* 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) {
// 特殊情况:传入的二叉树为空直接返回
if (!root || root.length === 0) {
return root
}
let list = []
helper(root)
// 遍历所有节点
for (let i = 0; i < list.length - 1; i++) {
let node = list[i],
nextNode = list[i + 1]
node.left = null
node.right = nextNode
}
// 收集节点
function helper(node) {
if (node !== null) {
list.push(node)
helper(node.left)
helper(node.right)
}
}
}
其他解法
- 递归时已经遍历了所有节点
- 那么可以尝试不生成真实的 list,在遍历时就拼接二叉树
- 先 left 后 right
- 从根节点遍历时遇到 left 节点就将其遍历插入到 原跟节点 right 之前
- 根节点->leftNode-start-left->leftNode-end-right->rightNode
1
/ \
2 5
/ \ \
3 4 6
----------------------=>
1
\
2
/ \
3 4
\
5
\
6
----------------------=>
1
\
2
\
3
\
4
\
5
\
6
var flatten = function (root) {
// 特殊情况:传入的二叉树为空直接返回
if (!root || root.length === 0) {
return root
}
function helper(node) {
if (node !== null) {
// 当前节点右侧节点
let right = node.right
// 将左节点放置到右节点 清除左节点,
node.right = node.left
node.left = null
// 遍历当前节点原左节点的右节点的根节点,使其余当前节点right节点连接
let rightEnd = node
while (rightEnd.right) {
rightEnd = rightEnd.right
}
rightEnd.right = right
// 右侧拼接的还有分支继续拼接
helper(node.right)
}
}
helper(root)
}
博客: 小书童博客
每天的每日一题,写的题解会同步更新到公众号一天一大 lee 栏目
欢迎关注留言
公号: 坑人的小书童