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

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

时间:2023-06-14 21:04:25浏览次数:53  
标签:输出 TreeNode val level number queue 深度 节点

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)
}

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

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);
}

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

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;
}

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

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,则其_二叉树_04

标签:输出,TreeNode,val,level,number,queue,深度,节点
From: https://blog.51cto.com/moonfdd/6481055

相关文章

  • 利用Theano理解深度学习——Multilayer Perceptron
    一、多层感知机MLP1、MLP概述对于含有单个隐含层的多层感知机(single-hidden-layerMulti-LayerPerceptron,MLP),可以将其看成是一个特殊的Logistic回归分类器,这个特殊的Logistic回归分类器首先通过一个非线性变换(non-lineartransformation)对样本的输入进行非线性变换,然后将变......
  • 利用Theano理解深度学习——Auto Encoder
    注:本系列是基于参考文献中的内容,并对其进行整理,注释形成的一系列关于深度学习的基本理论与实践的材料,基本内容与参考文献保持一致,并对这个专题起名为“利用Theano理解深度学习”系列,若文中有任何问题欢迎咨询。本文提供PDF版本,欢迎索取。“利用Theano理解深度学习”系列分为个部分,......
  • 【数据结构与算法面试题】二叉树节点的最大距离
    题目来源“数据结构与算法面试题80道”。问题分析:涉及的知识点是二叉树的遍历,遍历的方法主要有:先序遍历中序遍历后序遍历层次遍历在本题中,使用先序遍历的方法。方法:voidm_length(BSTreeNode*root,int*length,int*max_length){if(NULL==root||(NULL==root......
  • 利用Binary Hash Codes的深度图像检索
    1.概述本文的重点:图像的binaryhashcode的生成方法两阶段的检索方法——coarse-to-finesearchstrategy2.基于内容的图像检索2.1.基于内容的图像检索基于内容的图像检索(Content-basedImageRetrieval,CBIR)旨在通过对图像内容的分析搜索出相似的图像,其主要的工作有如下两点:图像......
  • 深度网络CTR建模
    1.概述CTR预估是现如今的搜索、推荐以及广告中必不可少的一部分,CTR预估的目标是预估用户点击给定item的概率。经过这么多年的发展,CTR预估算法得到了较大的改进,从开始的线性模型LR,发展到带有特征交叉的FM算法,随着深度网络的发展,CTR预估也逐渐发展到如今的基于深度模型的CTR预估,期间......
  • 微软亚洲工程院面试题:寻找两个二叉树节点的最近祖先
    给定一颗二叉树,并指定二叉树中任意两个节点,要求找出这两个节点在二叉树中的最近祖先,假定二叉树每个节点都有一个指向其父节点的指针,图中没有画出来,要求算法的空间复杂度必须是O(1),时间复杂度为O(h)。例如给定下面二叉树:如果指定的两个节点是401和257,那么他们的最近祖先就是节点1......
  • 深度学习:基本概念深度解析
    我们前面经过了三个实际项目的历练,在项目实践中我们其实在不自觉中经历了深度学习的重要步骤,以及践行了深度学习过程中的一些重要概念,再此我们把这些概念提炼出来加以阐述和理解,这能为我们后面进行难度更大的项目打下扎实的基础,我们需要搞清楚三个概念,分别是数据预加工,特征工程,以及......
  • 利用DSF深度优先搜索来解容器倒水问题
    在一些面试算法或智力题中,时不时会遇到容器倒水的问题,例如,有三个容器,分别是10升,7升,4升,7升和4升的容器装满了水,10升容器是空的,如果将容器a中的水倒入容器b时,必须使得a中的水全部倒完,或者b被倒满,问有没有一种倒水序列,使得7升容器或4升容器中只有2升的水。这个问题怎么会跟图论的深度......
  • 算法面试:单向链表节点的奇偶排序。
    给定一个单项链表,要求实现一个算法,把链表分成两部分,前一部分全是下标为偶数的节点,后一部分全是下标为奇数的节点,例如给定链表为下图的第一个队列,要求编写一个算法,将链表转换为第二个队列:要求算法不能分配多余的内存,同时,在操作链表是,不能更改节点内部的内容,只能更改节点的next指针......
  • 面试算法:获取重合列表的第一个相交节点
    给定两个单向链表,这两个链表有可能会有重叠,情况如下:两个单向链表从节点5开始重合,要求给定一个空间复杂度为O(1)的算法,返回两个链表相交时的第一个节点。依据上图,也就是返回节点5.首先我们需要做的是,确保给定的两个单向链表,他们是相交的。这个很好确定,只要从头遍历两个链表,如果他们......