OD_2024_C卷_200分_4、二叉树计算【JAVA】【二叉树前序、中序遍历】

在这里插入图片描述
在这里插入图片描述

代码

package odjava;

import java.util.*;

public class 四_二叉树计算 {
    static class TreeNode {
        int num; // 当前节点的值
        int childSum; // 当前节点的左子树+右子树的和
        TreeNode leftChild;
        TreeNode rightChild;

        public TreeNode(int num) {
            this.num = num;
            this.childSum = 0;
            this.leftChild = null;
            this.rightChild = null;
        }
    }

    // 中序遍历序列
    static int[] midOrder;
    // 前序遍历序列
    static int[] preOrder;
    // 记录中序遍历序列中,序列元素值所在位置,本题中可能存在重复元素,因此某个序列元素值可能有多个位置
    static HashMap<Integer, ArrayList<Integer>> midIndexMap = new HashMap<>();

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        midOrder = Arrays.stream(sc.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();
        preOrder = Arrays.stream(sc.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();

        int n = midOrder.length;
        for (int i = 0; i < n; i++) {
            int num = midOrder[i];
            midIndexMap.putIfAbsent(num, new ArrayList<>());
            midIndexMap.get(num).add(i);
        }

        // 根据中序序列和前序序列还原树结构
        TreeNode root = buildTree(0, n - 1, 0, n - 1);

        // 记录新的二叉树的的中序遍历序列
        StringJoiner sj = new StringJoiner(" ");
        getMidOrder(root, sj);
        System.out.println(sj);
    }

    // 二叉树中序遍历
    public static void getMidOrder(TreeNode root, StringJoiner sj) {
        if (root == null) {
            return;
        }
        // 先遍历左子树
        TreeNode leftChild = root.leftChild;
        if (leftChild != null) {
            getMidOrder(leftChild, sj);
        }
        // 再遍历根
        sj.add(root.childSum + "");
        // 最后遍历右子树
        TreeNode rightChild = root.rightChild;
        if (rightChild != null) {
            getMidOrder(rightChild, sj);
        }
    }

    /**
     * 根据中序遍历序列、前序遍历序列还原树结构
     *
     * @param midL 中序遍历子序列的左边界
     * @param midR 中序遍历子序列的右边界
     * @param preL 前序遍历子序列的左边界
     * @param preR 前序遍历子序列的右边界
     * @return 树结构的根节点
     */
    public static TreeNode buildTree(int midL, int midR, int preL, int preR) {
        // 某个节点(子树)对应一段子序列,如果对应子序列范围不存在,则子树也不存在
        if (preL > preR) return null;

        // 先根据前序遍历序列得到根节点,前序序列的首元素就是根节点
        int rootNum = preOrder[preL];
        TreeNode root = new TreeNode(rootNum);

        // 在中序遍历序列中,找到对应根值的位置,这个位置可能有多个,但是只有一个是正确的
        for (int idx : midIndexMap.get(rootNum)) {
            // 如果对应根值位置越界,则不是正确的
            if (idx < midL || idx > midR) continue;

            // 如果中序的左子树,和前序的左子树不同,则对应根值位置不正确
            int leftLen = idx - midL;
            if (notEquals(midL, preL + 1, leftLen)) continue;

            // 如果中序的右子树,和前序的右子树不同,则对应根值位置不正确
            int rightLen = midR - idx;
            if (notEquals(idx + 1, preR - rightLen + 1, rightLen)) continue;

            // 找到正确根值位置后,开始分治递归处理左子树和右子树
            root.leftChild = buildTree(midL, idx - 1, preL + 1, preL + leftLen);
            root.rightChild = buildTree(idx + 1, midR, preR - rightLen + 1, preR);

            // 记录该节点:左子树+右子树的和(本题新二叉树节点的值)
            root.childSum = (root.leftChild == null ? 0 : (root.leftChild.num + root.leftChild.childSum)) + (root.rightChild == null ? 0 : (root.rightChild.num + root.rightChild.childSum));

            break;
        }

        return root;
    }

    /**
     * 判断两个子数组是否相同(元素相同,顺序可以不同)
     *
     * @param midL 子数组1的左边界
     * @param preL 子数组2的左边界
     * @param size 子数组的长度
     * @return 子数组1和子数组2是否相同
     */
    public static boolean notEquals(int midL, int preL, int size) {
        int[] arr1 = Arrays.stream(Arrays.copyOfRange(midOrder, midL, midL + size)).sorted().toArray();
        int[] arr2 = Arrays.stream(Arrays.copyOfRange(preOrder, preL, preL + size)).sorted().toArray();

        for (int i = 0; i < size; i++) {
            if (arr1[i] != arr2[i]) {
                return true;
            }
        }

        return false;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/457064.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

嵌入式常用5种通信协议

简介&#xff1a; 嵌入式常用五种通信协议为&#xff1a;UART、RS232、RS485、IIC、SPI。 由于这几种通信协议十分相似又有区别&#xff0c;所以分组记忆&#xff0c;红色的为一组&#xff0c;蓝色的为一组。 ①组都有两条线&#xff0c;且都是异步通信没得时钟线&#xff0c…

基于springboot校园资产管理系统

现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本校园资产管理就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息&#xff0…

Baumer工业相机堡盟工业相机如何通过NEOAPISDK实现双快门采集两张曝光时间非常短的图像(C++)

Baumer工业相机堡盟工业相机如何通过NEOAPISDK实现双快门采集两张曝光时间非常短的图像&#xff08;C&#xff09; Baumer工业相机Baumer工业相机定序器功能的技术背景Baumer工业相机通过NEOAPI SDK使用定序器功能预期的相机动作技术限制定序器的工作原理 Baumer工业相机通过NE…

缩写

解法&#xff1a; 看字符串首元素即可 #include<iostream> #include<vector> #include<string> #include<sstream> using namespace std; #define endl \n void solve() {cin >> ws;string s, str;getline(cin, s);stringstream ss(s);while (…

Pretrain-finetune、Prompting、Instruct-tuning训练方法的区别

来自&#xff1a;【多模态】28、LLaVA 第一版 | Visual Instruction Tuning 多模态模型的指令微调_多模态指令跟随数据-CSDN博客 几种模型训练方法的区别&#xff1a; 1、Pretrain-finetune&#xff1a;先在大量数据集上做预训练&#xff0c;然后针对某个子任务做 finetune 2…

11GR2 rac 2节点一键安装演示

Oracle 一键安装脚本&#xff0c;演示 2 节点 RAC 一键安装过程&#xff08;全程无需人工干预&#xff09;&#xff1a;&#xff08;脚本包括 GRID/ORALCE PSU/OJVM 补丁自动安装&#xff09; ⭐️ 脚本下载地址&#xff1a;Shell脚本安装Oracle数据库 脚本第三代支持 N 节点…

LLVM-3.5 —— 01记,编译 LLVM 3.5.0 clang and clang-query

包括编译&#xff1a;clang clang-tools-extra 0, prepare env sudo apt install llvm sudo apt install clang 使用最新的g 会出错。 1, source code $ git clone --recursive $ cd llvm-project $ git checkout llvmorg-3.5.0 $ cp -r ./clang ./llvm/tools/ $ mkdir llv…

为什localhost被forbidden而127.0.0.1不被绊?

原因&#xff1a; 判段网关的时候判127.0.0.1&#xff0c;所以最好改localhost 其他参考&#xff1a; 【计算机网络】localhost不能访问&#xff0c;127.0.0.1可以访问&#xff1f;_ping localhost和ping 127.0.0.1-CSDN博客

如何关闭 Visual Studio 双击异常高亮

[问题描述]&#xff1a; 最近 Visual Studio 更新后&#xff0c;双击选中关键字快要亮瞎我的眼睛了 &#x1f440;&#x1f440; [解决方法]&#xff1a; 摸索了一下&#xff0c;找到了关闭的方法&#xff1a;工具 → 选项 → 文本编辑器 → 常规&#xff0c;然后取消 勾选 sel…

C#使用MiniExcel读取excel表格文件

使用MiniExcel读取excel表格文件 MiniExecl提供了几种读取方法。 准备测试数据 测试类&#xff1a; public class Person{public int Id { get; set; }public string Name { get; set; }public string Description { get; set; }public double Value { get; set; }}测试数据…

2023年全球运维大会(GOPS上海站):运维精英齐聚一堂,共探行业新知(附大会核心PPT下载)

随着信息技术的飞速发展&#xff0c;运维作为保障企业信息化系统稳定运行的关键环节&#xff0c;其重要性日益凸显。GOPS 主要面向运维行业的中高端技术人员&#xff0c;包括运维、开发、测试、架构师等群体。目的在于帮助IT技术从业者系统学习了解相关知识体系&#xff0c;让创…

Docker容器化技术(使用Docker搭建论坛)

第一步&#xff1a;删除容器镜像文件 [rootlocalhost ~]# docker rm -f docker ps -aq b09ee6438986 e0fe8ebf3ba1第二步&#xff1a;使用docker拉取数据库 [rootlocalhost ~]# docker run -d --name db mysql:5.7 02a4e5bfffdc81cb6403985fe4cd6acb0c5fab0b19edf9f5b8274783…

RocketMQ—如何解决消息堆积问题

RocketMQ—如何解决消息堆积问题 一般认为单条队列消息差值大于等于10万时&#xff0c;就算消息队列了。 生产者生产速度远远大于消费者消费的速度 我们可以增加消费者数量&#xff0c;但是需要满足消费者数量 小于等于 队列数量。 一般消费方消费消息是IO操作&#xff0c;…

Leetcode 118. 杨辉三角

题目描述&#xff1a; 给定一个非负整数 numRows&#xff0c;生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 示例 1: 输入: numRows 5 输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]] 示例 2: 输入: numRows 1 输…

Logstash 详细介绍、安装与使用

目录 1. Logstash 概述2. 工作原理3. 安装和配置1. 安装&#xff08;两种方法&#xff09;2. 测试运行3. 配置输入和输出 4. 使用 Grok 过滤器插件解析 Web 日志5. 使用 Geoip 过滤器插件增强数据6. 配置接收 Beats 的输入 1. Logstash 概述 Logstash 是一个具有实时管道功能的…

手把手教你苹果MacBook电脑清理内存怎么清理?

随着时间的推移&#xff0c;我们的电脑上总会不知不觉地堆积起各种各样的应用和文件。有些应用可能只是一时兴起安装&#xff0c;用过一次之后便束之高阁&#xff1b;有些文件则是工作、学习中产生的&#xff0c;但随着时间的推移已经变得毫无用处。这些不常用的应用和无用文件…

自己写的whoami

一、代码 #include<stdio.h> #include<stdlib.h> #include<proc/readproc.h> int main() {struct PROCTAB *pt;struct proc_t *p;char *cmd;ptmalloc(sizeof(struct PROCTAB));pmalloc(sizeof(struct proc_t));ptopenproc(0x0028);while(readproc(pt,p)!NUL…

C++ :内存管理 newdelete

目录 内存区域划分 C的动态内存的管理方式 new new的基本使用方法 【注意事项】 delete 【注意】 new和delete操作自定义类型 operator new 和 operator delete 【关于自定义类型new申请内存】 【原理】 【调用顺序】 【连续开辟空间问题】 malloc/free和…

数据结构 -- 第1章 绪论

1.1.3 起泡排序 局部有序与整体有序 在由一组整数组成的序列A[0, n - 1]中&#xff0c;满足A[i - 1] ≤ A[i]的相邻元素称作顺序的&#xff1b;否则是逆序的。 有序序列中每一对相邻元素都是顺序的&#xff0c;所有相邻元素均顺序的序列&#xff0c;也必然整体有序。 扫描交…

Profinet转CC-LINK网关功能与配置方法

CC-LINK转Profinet网关&#xff08;XD-PNCR20&#xff09;支持CC-Link系统&#xff0c;采用一种开放式架构的工业现场总线协议&#xff0c;允许不同厂商的设备依此协议进行通信。由于其良好的兼容性&#xff0c;CC-Link广泛使用在在制造产业中的机器控制或程序控制中&#xff0…
最新文章