leetcode地址:从先序遍历还原二叉树
我们从二叉树的根节点 root 开始进行深度优先搜索。
在遍历中的每个节点处,我们输出 D 条短划线(其中 D 是该节点的深度),然后输出该节点的值。(如果节点的深度为 D,则其直接子节点的深度为 D + 1。根节点的深度为 0)。
如果节点只有一个子节点,那么保证该子节点为左子节点。
给出遍历输出 S,还原树并返回其根节点 root。
示例 1:
输入:“1-2–3–4-5–6–7”
输出:[1,2,5,3,4,6,7]
示例 2:
输入:“1-2–3—4-5–6—7”
输出:[1,2,5,3,null,6,null,4,null,7]
示例 3:
输入:“1-401–349—90–88”
输出:[1,401,null,349,88,90]
提示:
原始树中的节点数介于 1 和 1000 之间。
每个节点的值介于 1 和 10 ^ 9 之间。
实现思路
根据给定的深度优先搜索遍历输出字符串 S 还原出原始的二叉树。深度优先搜索的遍历顺序是前序遍历(即根节点->左子树->右子树),并且每个节点的深度由前面的短划线数决定。
解析字符串
首先解析字符串 S,找到每个节点的值和其深度。
用两个指针遍历字符串,一个用来确定深度,另一个用来读取节点的值。
构建树
用一个栈来辅助构建树。栈中的元素按深度递增顺序保存正在处理的节点。
遍历每个节点,根据深度确定其父节点,然后将其添加到树中。
如果当前节点的深度小于或等于栈顶节点的深度,弹出栈顶节点直到栈顶节点的深度小于当前节点的深度。
将当前节点加入到其父节点的左或右子树中,并将当前节点压入栈中。
代码详解
# 定义二叉树节点类
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def recoverFromPreorder(S: str) -> TreeNode:
# 辅助函数:解析节点值和深度
def parse_node(S, index):
depth = 0
while index < len(S) and S[index] == '-':
depth += 1
index += 1
start = index
while index < len(S) and S[index].isdigit():
index += 1
value = int(S[start:index])
return value, depth, index
stack = []
index = 0
while index < len(S):
value, depth, index = parse_node(S, index)
node = TreeNode(value)
while len(stack) > depth:
stack.pop()
if stack:
if not stack[-1].left:
stack[-1].left = node
else:
stack[-1].right = node
stack.append(node)
return stack[0]
# 测试示例
S = "1-2--3--4-5--6--7"
root = recoverFromPreorder(S)
# 辅助函数:前序遍历打印树节点值
def print_tree_preorder(node):
if not node:
return
print(node.val, end=' ')
print_tree_preorder(node.left)
print_tree_preorder(node.right)
# 打印还原的树
print_tree_preorder(root)
go实现
package main
import (
"fmt"
"strconv"
"strings"
)
// TreeNode is a binary tree node.
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
// recoverFromPreorder parses a preorder traversal string and constructs the binary tree.
func recoverFromPreorder(S string) *TreeNode {
stack := []*TreeNode{}
index := 0
for index < len(S) {
// Determine the depth
depth := 0
for index < len(S) && S[index] == '-' {
depth++
index++
}
// Determine the value
start := index
for index < len(S) && S[index] >= '0' && S[index] <= '9' {
index++
}
val, _ := strconv.Atoi(S[start:index])
node := &TreeNode{Val: val}
// Ensure the stack matches the current depth
for len(stack) > depth {
stack = stack[:len(stack)-1]
}
// Attach the node to its parent
if len(stack) > 0 {
if stack[len(stack)-1].Left == nil {
stack[len(stack)-1].Left = node
} else {
stack[len(stack)-1].Right = node
}
}
// Push the current node onto the stack
stack = append(stack, node)
}
// The first element in the stack is the root node
return stack[0]
}
// Helper function to print the tree in preorder (root, left, right)
func printTreePreorder(node *TreeNode) {
if node == nil {
return
}
fmt.Print(node.Val, " ")
printTreePreorder(node.Left)
printTreePreorder(node.Right)
}
func main() {
S := "1-2--3--4-5--6--7"
root := recoverFromPreorder(S)
printTreePreorder(root)
}
kotlin实现
class TreeNode(var `val`: Int) {
var left: TreeNode? = null
var right: TreeNode? = null
}
fun recoverFromPreorder(S: String): TreeNode? {
val stack = mutableListOf<TreeNode>()
var index = 0
while (index < S.length) {
// Determine the depth
var depth = 0
while (index < S.length && S[index] == '-') {
depth++
index++
}
// Determine the value
val start = index
while (index < S.length && S[index].isDigit()) {
index++
}
val value = S.substring(start, index).toInt()
val node = TreeNode(value)
// Ensure the stack matches the current depth
while (stack.size > depth) {
stack.removeAt(stack.size - 1)
}
// Attach the node to its parent
if (stack.isNotEmpty()) {
if (stack.last().left == null) {
stack.last().left = node
} else {
stack.last().right = node
}
}
// Push the current node onto the stack
stack.add(node)
}
return stack.firstOrNull()
}
// Helper function to print the tree in preorder (root, left, right)
fun printTreePreorder(node: TreeNode?) {
if (node == null) return
print("${node.`val`} ")
printTreePreorder(node.left)
printTreePreorder(node.right)
}
fun main() {
val S = "1-2--3--4-5--6--7"
val root = recoverFromPreorder(S)
printTreePreorder(root)
}