2023-06-14:我们从二叉树的根节点 root 开始进行深度优先搜索。

在遍历中的每个节点处,我们输出 D 条短划线(其中 D 是该节点的深度)

然后输出该节点的值。(如果节点的深度为 D,则其直接子节点的深度为 D + 1

根节点的深度为 0

如果节点只有一个子节点,那么保证该子节点为左子节点

给出遍历输出 S,还原树并返回其根节点 root。

输入:"1-2--3--4-5--6--7"。

输出:[1,2,5,3,4,6,7]。

答案2023-06-14:

大体过程如下:

1.根据输入的遍历字符串 S 来构建一个二叉树。

2.定义一个结构体类型 TreeNode,表示二叉树的节点,包括节点值 Val,左子节点 Left,右子节点 Right。

3.定义一个数组 queue,用于存储节点的深度和值。

4.定义两个全局变量 l 和 r,表示队列的左右指针。

5.定义一个函数 recoverFromPreorder,用于根据遍历字符串 S 还原二叉树。

6.遍历字符串 S 的每一个字符:

a.如果该字符不为 '-'(即为数字字符),记录下该数字,直到该数字记录完毕。

b.如果该字符为 '-',则表示该数字已经记录完毕,将该数字加入到 queue 数组中,并将 pickLevel 置为 true。

c.如果该字符是 '-' 或者到达字符串末尾,表示该数字已经记录完毕,将 lvel 记录到队列中, pickLevel 置为 false 。

d.如果该字符是 '-',表示深度加 1;否则,将该数字加入到 number 中。

7.处理掉最后一个数字,将其加入到队列 queue 中。

8.定义一个递归函数 f,用于生成节点,并构建二叉树。

9.取出队列的第一个元素 level,它是当前节点的深度。

10.取出队列的第二个元素 val,它是当前节点的值。

11.生成一个 TreeNode 类型的结构体,元素值为 val,左子节点和右子节点置为 nil。

12.如果队列不为空,且队列的下一个元素的值大于当前节点深度 level,则递归进入左子节点,生成左子树。

13.同样,如果队列不为空,且队列的下一个元素的值大于当前节点深度 level,则递归进入右子节点,生成右子树。

14.返回根节点 head。

时间复杂度为 O(n),其中 n 是遍历字符串 S 的长度。需要遍历字符串 S 一次,并将每个节点入队一次,然后根据队列中的节点数构建二叉树,构建二叉树的时间复杂度也是 O(n)。因此,总时间复杂度为 O(n)。

空间复杂度为 O(n),需要一个数组来存储节点的深度和值,并将其入队。由于二叉树不一定是满二叉树,因此最多需要存储 2n 个节点的深度和值信息。因此,总空间复杂度为 O(n)。

go完整代码如下:

package main

import (
"fmt"
"strconv"
) type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
} const MAXN = 2001 var queue [MAXN]int
var l, r int func recoverFromPreorder(traversal string) *TreeNode {
l = 0
r = 0
number := 0
level := 0
pickLevel := true
for i := 0; i < len(traversal); i++ {
c := traversal[i]
if c != '-' {
if pickLevel {
queue[r] = level
level = 0
r++
pickLevel = false
}
d, _ := strconv.Atoi(string(c))
number = number*10 + d
} else {
if !pickLevel {
queue[r] = number
number = 0
r++
pickLevel = true
}
level++
}
}
queue[r] = number
return f()
} func f() *TreeNode {
level := queue[l]
head := &TreeNode{Val: queue[l+1], Left: nil, Right: nil}
l += 2
if l < r && queue[l] > level {
head.Left = f()
}
if l < r && queue[l] > level {
head.Right = f()
}
return head
} func main() {
traversal := "1-2--3--4-5--6--7"
result := recoverFromPreorder(traversal)
fmt.Printf("%+v\n", result)
}

rust完整代码如下:

use std::cell::RefCell;
use std::rc::Rc;
#[derive(Debug, PartialEq, Eq)]
pub struct TreeNode {
pub val: i32,
pub left: Option<Rc<RefCell<TreeNode>>>,
pub right: Option<Rc<RefCell<TreeNode>>>,
} impl TreeNode {
#[inline]
pub fn new(val: i32) -> Self {
TreeNode {
val,
left: None,
right: None,
}
}
} fn recover_from_preorder(traversal: String) -> Option<Rc<RefCell<TreeNode>>> {
let mut queue = vec![0; 2001];
let mut l = 0;
let mut r = 0;
let mut number = 0;
let mut level = 0;
let mut pick_level = true;
for c in traversal.chars() {
if c != '-' {
if pick_level {
queue[r] = level;
level = 0;
r += 1;
pick_level = false;
}
number = number * 10 + c.to_digit(10).unwrap() as i32;
} else {
if !pick_level {
queue[r] = number;
number = 0;
r += 1;
pick_level = true;
}
level += 1;
}
}
queue[r] = number;
let queue_len = r + 1;
f(&mut queue, &mut l, queue_len, 0)
} fn f(queue: &mut [i32], l: &mut usize, r: usize, level: i32) -> Option<Rc<RefCell<TreeNode>>> {
if *l >= r || queue[*l] != level {
None
} else {
*l += 1;
let head = Rc::new(RefCell::new(TreeNode::new(queue[*l])));
*l += 1;
head.borrow_mut().left = f(queue, l, r, level + 1);
head.borrow_mut().right = f(queue, l, r, level + 1);
Some(head)
}
} fn main() {
let traversal = String::from("1-2--3--4-5--6--7");
let result = recover_from_preorder(traversal);
println!("{:#?}", result);
}

c++完整代码如下:

#include <iostream>
#include <vector>
using namespace std; struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode() : val(0), left(nullptr), right(nullptr) {}
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
TreeNode(int x, TreeNode* left, TreeNode* right) : val(x), left(left), right(right) {}
}; TreeNode* f(); const int MAXN = 2001;
int queue[MAXN];
int l, r; TreeNode* recoverFromPreorder(string traversal) {
l = 0;
r = 0;
int number = 0;
int level = 0;
bool pickLevel = true;
for (int i = 0; i < traversal.size(); i++) {
char c = traversal[i];
if (c != '-') {
if (pickLevel) {
queue[r++] = level;
level = 0;
pickLevel = false;
}
number = number * 10 + c - '0';
}
else {
if (!pickLevel) {
queue[r++] = number;
number = 0;
pickLevel = true;
}
level++;
}
}
queue[r++] = number;
return f();
} TreeNode* f() {
int level = queue[l++];
TreeNode* head = new TreeNode(queue[l++]);
if (l < r && queue[l] > level) {
head->left = f();
}
if (l < r && queue[l] > level) {
head->right = f();
}
return head;
} int main() {
string traversal = "1-2--3--4-5--6--7";
TreeNode* result = recoverFromPreorder(traversal);
cout << result->val << endl;
cout << result->left->val << endl;
cout << result->right->val << endl;
cout << result->left->left->val << endl;
cout << result->left->right->val << endl;
cout << result->right->left->val << endl;
cout << result->right->right->val << endl;
return 0;
}

c语言完整代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h> struct TreeNode {
int val;
struct TreeNode* left;
struct TreeNode* right;
}; struct TreeNode* f(); #define MAXN 2001 int queue[MAXN];
int l, r; struct TreeNode* recoverFromPreorder(char* traversal) {
l = 0;
r = 0;
int number = 0;
int level = 0;
int pickLevel = 1;
int len = strlen(traversal);
for (int i = 0; i < len; i++) {
char c = traversal[i];
if (c != '-') {
if (pickLevel) {
queue[r++] = level;
level = 0;
pickLevel = 0;
}
number = number * 10 + c - '0';
}
else {
if (!pickLevel) {
queue[r++] = number;
number = 0;
pickLevel = 1;
}
level++;
}
}
queue[r++] = number;
return f();
} struct TreeNode* f() {
int level = queue[l++];
struct TreeNode* head = (struct TreeNode*)malloc(sizeof(struct TreeNode));
head->val = queue[l++];
head->left = NULL;
head->right = NULL;
if (l < r && queue[l] > level) {
head->left = f();
}
if (l < r && queue[l] > level) {
head->right = f();
}
return head;
} int main() {
char traversal[] = "1-2--3--4-5--6--7";
struct TreeNode* result = recoverFromPreorder(traversal);
printf("%d\n", result->val);
printf("%d\n", result->left->val);
printf("%d\n", result->right->val);
printf("%d\n", result->left->left->val);
printf("%d\n", result->left->right->val);
printf("%d\n", result->right->left->val);
printf("%d\n", result->right->right->val);
return 0;
}

2023-06-14:我们从二叉树的根节点 root 开始进行深度优先搜索。 在遍历中的每个节点处,我们输出 D 条短划线(其中 D 是该节点的深度) 然后输出该节点的值。(如果节点的深度为 D,则其的更多相关文章

  1. C#图片灰度处理(位深度24→位深度8)、C#图片二值化处理(位深度8→位深度1)

    C#图片灰度处理(位深度24→位深度8) #region 灰度处理 /// <summary> /// 将源图像灰度化,并转化为8位灰度图像. /// </summary> / ...

  2. CF F - Tree with Maximum Cost (树形DP)给出你一颗带点权的树,dist(i, j)的值为节点i到j的距离乘上节点j的权值,让你任意找一个节点v,使得dist(v, i) (1 < i < n)的和最大。输出最大的值。

    题目意思: 给出你一颗带点权的树,dist(i, j)的值为节点i到j的距离乘上节点j的权值,让你任意找一个节点v,使得dist(v, i) (1 < i < n)的和最大.输出最大的值. ...

  3. 二叉树 Java 实现 前序遍历 中序遍历 后序遍历 层级遍历 获取叶节点 宽度 ,高度,队列实现二叉树遍历 求二叉树的最大距离

    数据结构中一直对二叉树不是很了解,今天趁着这个时间整理一下 许多实际问题抽象出来的数据结构往往是二叉树的形式,即使是一般的树也能简单地转换为二叉树,而且二叉树的存储结构及其算法都较为简单,因此二叉树显 ...

  4. Leetcode之深度优先搜索(DFS)专题-129. 求根到叶子节点数字之和(Sum Root to Leaf Numbers)

    Leetcode之深度优先搜索(DFS)专题-129. 求根到叶子节点数字之和(Sum Root to Leaf Numbers) 深度优先搜索的解题详细介绍,点击 给定一个二叉树,它的每个结点都存放 ...

  5. Leetcode之深度优先搜索(DFS)专题-1080. 根到叶路径上的不足节点(Insufficient Nodes in Root to Leaf Paths)

    Leetcode之深度优先搜索(DFS)专题-1080. 根到叶路径上的不足节点(Insufficient Nodes in Root to Leaf Paths) 这篇是DFS专题的第一篇,所以我会 ...

  6. 二叉树系列 - 二叉搜索树 - [LeetCode] 中序遍历中利用 pre节点避免额外空间。题:Recover Binary Search Tree,Validate Binary Search Tree

    二叉搜索树是常用的概念,它的定义如下: The left subtree of a node contains only nodes with keys less than the node's ke ...

  7. http://www.cnblogs.com/huangcong/archive/2010/06/14/1757957.html

    http://www.cnblogs.com/huangcong/archive/2010/06/14/1757957.html http://www.cnblogs.com/langtianya/a ...

  8. httppost的用法(NameValuePair(简单名称值对节点类型)核心对象)

    一,案例一 定义了一个list,该list的数据类型是NameValuePair(简单名称值对节点类型),这个代码多处用于Java像url发送Post请求.在发送post请求时用该list来存放参数. ...

  9. 输出redis cluster 主从的对应关系,如果同一个主从关系的master和slave在同一个node节点上,在输出的对应关系末尾输出提示

    需求:输出redis cluster 主从的对应关系,如果同一个主从关系的master和slave在同一个node节点上,在输出的对应关系末尾输出提示. 为什么会有这样的需求呢?在重新搭建redis ...

  10. Leetcode之深度优先搜索(DFS)专题-513. 找树左下角的值(Find Bottom Left Tree Value)

    Leetcode之深度优先搜索(DFS)专题-513. 找树左下角的值(Find Bottom Left Tree Value) 深度优先搜索的解题详细介绍,点击 给定一个二叉树,在树的最后一行找到最 ...

随机推荐

  1. ES(ECMAScript)标准下中的let、var和const

    ES标准下中的let,var和const let会报重复声明,var则比较随意,重不重复无所谓 // 使用 var 的时候重复声明变量是没问题的,只不过就是后面会把前面覆盖掉 var num = 10 ...

  2. w10共享打印机出现011b错误

    错误描述:在更新里面没有发现所说的500补丁,可就是报上面的错误,然后百度找答案 解决方案1 WIN10无法连接共享打印机0x0000011b的解决方法,不用卸载更新,在共享打印机的电脑上,打开注册表 ...

  3. [智能制造] 如何利用生产软件(MES)进行生产信息收集?

    1 如何保证生产管理软件所收集信息的准确性? 1.1 当前制造企业使用MES系统收集信息的现状 原以为使用了MES生产管理系统后,会得到稽核员的肯定. 但没想到,在实际的稽核过程中,稽核员还是发现目前 ...

  4. 四月十九号java基础知识

    1.总括:类的继承是使用已有的类为基础派生出新的类.通过类继承的方式,便能开发出新的类,而不需要编写相同的程序代码,所以说类的继承是程序代码再利用的概念抽象与接口都是类概念的扩展.通过继承扩展出的子类 ...

  5. 五月十五日java基础知识点

    1.匿名内部类适用于编写事件程序 interface Ishape{ void shape(); } class MyType{ public void outShape(Ishape s){//接口 ...

  6. LeeCode 90双周赛复盘

    T1: 差值数组不同的字符串 思路:数组遍历 若前两个字符串差值数组不同,则只需要继续计算第三个字符串的差值数组即可得到答案 若前两个字符串差值数组相同,则依次遍历后续字符串,直至找到不同的差值数组 ...

  7. Go For Web:踏入Web大门的第一步——Web 的工作方式

    前言: 本文作为解决如何通过 Golang 来编写 Web 应用这个问题的前瞻,对 Golang 中的 Web 基础部分进行一个简单的介绍.目前 Go 拥有成熟的 Http 处理包,所以我们去编写一个 ...

  8. 开源后台管理系统解决方案 boot-admin 简介

    介绍 boot-admin 是一款采用前后端分离架构模式的后台管理框架.系统提炼自实际项目,兼具RuoYi-Vue前端分离版和Ruoyi-Cloud微服务版功能与技术特点. boot-admin 既有 ...

  9. 当我第一次通过Kotlin和Compose来实现一个Canvas时, 我收获了什么?

    当我第一次通过Kotlin和Compose来实现一个Canvas时, 我收获了什么? 自从2019年Google推荐Kotlin为Android开发的首选语言以来已经经历了将近四年的时间, Compo ...

  10. 云原生时代崛起的编程语言Go常用标准库实战

    @ 目录 基础标准库 简述 字符串-string 底层结构 函数 长度 格式化输出 模版-template text/template html/template 正则表达式-regexp 编码-en ...