20200618
我们从二叉树的根节点 root 开始进行深度优先搜索。
在遍历中的每个节点处,我们输出 D 条短划线(其中 D 是该节点的深度),然后输出该节点的值。(如果节点的深度为 D,则其直接子节点的深度为 D + 1。根节点的深度为 0)。
如果节点只有一个子节点,那么保证该子节点为左子节点。
给出遍历输出 S,还原树并返回其根节点 root。
1
/ \
2 3
/ \ / \
4 5 6 7
输入:"1-2--3--4-5--6--7"
输出:[1,2,5,3,4,6,7]
1
/ \
2 5
/ /
3 6
/ /
4 7
输入:"1-2--3---4-5--6---7"
输出:[1,2,5,3,null,6,null,4,null,7]
1
/
401
/ \
349 88
/
90
输入:"1-401--349---90--88"
输出:[1,401,null,349,88,90]
逻辑
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {string} S
* @return {TreeNode}
*/
var recoverFromPreorder = function (S) {
var level = 0,
value = 0
var _result = [new TreeNode(S.split('-')[0])]
for (let i = 1; i < S.length; i++) {
if (S[i] == '-') {
level++
value = 0
} else if (level > 0) {
value = value * 10 + Number(S[i])
if ((S[i + 1] && S[i + 1] === '-') || i === S.length - 1) {
var nodeTree = new TreeNode(value)
if (_result[level - 1].left == null) {
_result[level - 1].left = nodeTree
} else {
_result[level - 1].right = nodeTree
}
_result[level] = nodeTree
level = 0
}
}
}
return _result[0]
}
/**
* @param {number[]} A
* @return {number}
*/
var recoverFromPreorder = function (S) {
const stack = []
for (let i = 0; i < S.length;) {
let curLevel = 0 //一个curNode对应一个curLevel
while (i < S.length && S[i] == '-') { // 避免循环半途中出界
i++
curLevel++ // 连字符个数代表level
}
const start = i // 记录当前节点值的开始位置
while (i < S.length && S[i] != '-') {
i++ // 指针移到当前节点值的结束位置
}
const curNode = new TreeNode(S.slice(start, i)) //创建当前节点
if (stack.length == 0) { // ROOT入栈,不用找父亲,continue
stack.push(curNode)
continue
}
while (stack.length > curLevel) { // 栈顶不是父亲,栈顶出栈
stack.pop() // 直到栈顶是父亲
}
if (stack[stack.length - 1].left) { // 左儿子已存在
stack[stack.length - 1].right = curNode // 安排为右儿子
} else {
stack[stack.length - 1].left = curNode // 安排为左儿子
}
stack.push(curNode) // 节点肯定要入栈一次
}
return stack[0] // 栈底就是根节点
};
/**
* @param {number[]} A
* @return {number}
*/
var maxScoreSightseeingPair = function (A) {
if (!S) return null
const reg = new RegExp(`(?<=\\d)${char}(?=\\d)`),
[root, left, right] = S.split(reg),
treeNode = new TreeNode(+root);
treeNode.left = recoverFromPreorder(left, char + '-')
treeNode.right = recoverFromPreorder(right, char + '-')
return treeNode
}
// 配置 两个数字包含着的层级数[val-left,*-right]
/\d-{n}\d/g
// 跟 数字 -- 数字 切分字符串
/?<=\\d)${char}(?=\\d/g
博客: 小书童博客(http://gaowenju.com)
公号: 坑人的小书童