华为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);
    }
}
相关推荐
不一样的故事1269 小时前
芯片设计是一个高度复杂、分工精细的系统工程
数据结构·经验分享
数模竞赛Paid answer9 小时前
2026年五一杯数学建模C题边坡预警问题求解全过程文档及程序
算法·数学建模·五一杯
梁辰兴9 小时前
软件工程:面向数据结构的设计方法
数据结构·软件工程·梁辰兴·面向数据结构的设计方法·jackson方法·warnier方法·方法比较
hold?fish:palm9 小时前
20 旋转图像
c++·算法·leetcode
NoteStream10 小时前
【C语言基础】分支和循环(上)
c语言·开发语言·c++·经验分享·笔记·算法·c#
白狐_79810 小时前
408数据结构第7章:查找②——顺序、折半、分块查找秒杀 + 真题
数据结构·算法
卷心菜的学习路11 小时前
基于多模态向量检索的数学相似题推荐系统:完整设计、算法与实验
java·python·算法·大模型·推荐算法·数学相似题
小南知更鸟11 小时前
【leetcodehot100】leetcode-hot100-20260809更新
算法·leetcode·职场和发展
数模竞赛Paid answer11 小时前
2021年深圳杯数学建模A题火星探测器着陆控制方案解题全过程论文及程序
算法·数学建模·深圳杯
hold?fish:palm11 小时前
19 螺旋矩阵
线性代数·算法·矩阵