华为od(D卷)二叉树计算

文章目录

题目描述

给出一个二叉树如下图所示:

java 复制代码
     6
    / \
   7   9
    \  /  
    -2 6  

请由该二叉树生成一个新的二叉树,它满足其树中的每个节点将包含原始树中的左子树和右子树的和。

java 复制代码
      20 (7-2+9+6)
     /   \
    -2    6
     \   /  
     0  0 

左子树表示该节点左侧叶子节点为根节点的一颗新树;右子树表示该节点右侧叶子节点为根节点的一颗新树

输入描述

2行整数,

第1行表示二叉树的中序遍历,

第2行表示二叉树的前序遍历,以空格分割

例如:

7 -2 6 6 9

6 7 -2 9 6

输出描述

1行整数,表示求和树的中序遍历,以空格分割

例如:

输出1 -2 0 20 0 6

示例1

输入:

-3 12 6 8 9 -10 -7

8 12 -3 6 -10 9 -7
输出:

0 3 0 7 0 2 0

思路

1 . 前序中序构造二叉树

前序: 中左右; 判断"中"是第一个元素。

中序: 根据前序找到的"中" ,判断左右子树是谁。(此时可以提前计算左右子树的和)

代码

java 复制代码
public class Demo11 {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        // 中序
        int[] in = Arrays.stream(scanner.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();
        // 前序
        int[] pre = Arrays.stream(scanner.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();
        // 最终中序结果
        int[] resMid = new int[in.length];
        buildTree(pre, in, resMid, 0, pre.length, 0, in.length);
        System.out.println(Arrays.toString(resMid));
        scanner.close();

    }

    /**
     * @param pre      前序数组
     * @param in       中序数组
     * @param resMid   最终输出中序结果
     * @param preStart 前序开始索引
     * @param preEnd   前序结束索引
     * @param inStart  中序开始索引
     * @param inEnd    中序结束索引
     */
    public static void buildTree(int[] pre, int[] in, int[] resMid, int preStart, int preEnd, int inStart, int inEnd) {

        if (preStart == preEnd || inStart == inEnd) {
            return;
        }
        if (preEnd - preStart == 1 && inEnd - inStart == 1) {
            return;
        }
        
        // 中  为第一个元素
        int rootValue = pre[preStart];

        // 中  在中序中的位置
        int index = 0;
        for (int i = inStart; i < inEnd; i++) {
            if (in[i] == rootValue) {
                index = i;
                break;
            }
        }
        
        // 中序数组 左子树
        int inLeftStart = inStart;
        int inLeftEnd = index;
        // 中序数组的右子树
        int inRightStart = index + 1;
        int inRightEnd = inEnd;

        // 前序数组的  左子树
        int preLeftStart = preStart + 1;
        int preLeftEnd = preLeftStart + (index - inStart);
        // 前序数组的 右子树
        int preRightStart = preLeftEnd;
        int preRightEnd = preEnd;

        // 计算左右子树的和
        int[] inLeft = Arrays.copyOfRange(in, inLeftStart, inLeftEnd);
        int[] inRight = Arrays.copyOfRange(in, inRightStart, inRightEnd);
        resMid[index] = Arrays.stream(inLeft).sum() +
                Arrays.stream(inRight).sum();

        // 递归
        buildTree(pre, in, resMid, preLeftStart, preLeftEnd, inLeftStart, inLeftEnd);
        buildTree(pre, in, resMid, preRightStart, preRightEnd, inRightStart, inRightEnd);
    }
}
相关推荐
happymaker06267 小时前
LeetCodeHot100——128.最长连续序列
算法
余生皆假期-7 小时前
配置 CodeX 环境的 Simlink AI 工具链
笔记·单片机·嵌入式硬件·算法
qq_296553277 小时前
[特殊字符] 旋转排序数组中的高效搜索:从线性到二分查找的进阶之路
数据结构·算法·搜索引擎·分类·柔性数组
纪念 2298 小时前
顺序表(数据结构入门的开端)
数据结构
汉字萌萌哒8 小时前
2025 CSP-S提高级(第一轮)C++真题以及答案
数据结构·算法
明志数科8 小时前
仿真数据与真实数据:机器人训练的数据策略选择
人工智能·算法·机器学习
weyyhdke8 小时前
2026电源与MCU控制设计实战:用Gemini3.5镜像站免费优化开关电源环路与电机FOC算法硬核教程
单片机·嵌入式硬件·算法
小张成长计划..8 小时前
【C++】35:位图,布隆过滤器和海量数据处理(哈希扩展)
算法·哈希算法
z200509308 小时前
今日算法(组合问题III)(回溯的使用)
java·算法·leetcode
春栀怡铃声8 小时前
【C++修仙录02】筑基篇:list 使用
数据结构·list