华为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);
    }
}
相关推荐
泽虞5 分钟前
《Qt应用开发》笔记p5
linux·开发语言·c++·笔记·qt·算法
Swift社区8 小时前
LeetCode 394. 字符串解码(Decode String)
算法·leetcode·职场和发展
tt5555555555558 小时前
LeetCode进阶算法题解详解
算法·leetcode·职场和发展
让我们一起加油好吗8 小时前
【基础算法】DFS中的剪枝与优化
算法·深度优先·剪枝
Q741_1479 小时前
C++ 模拟题 力扣495. 提莫攻击 题解 每日一题
c++·算法·leetcode·模拟
Felven10 小时前
A. Be Positive
算法
小O的算法实验室10 小时前
2026年COR SCI2区,自适应K-means和强化学习RL算法+有效疫苗分配问题,深度解析+性能实测,深度解析+性能实测
算法·论文复现·智能算法·智能算法改进
青岛少儿编程-王老师10 小时前
CCF编程能力等级认证GESP—C++7级—20250927
数据结构·c++·算法
夏鹏今天学习了吗11 小时前
【LeetCode热题100(39/100)】对称二叉树
算法·leetcode·职场和发展
天选之女wow11 小时前
【代码随想录算法训练营——Day34】动态规划——416.分割等和子集
算法·leetcode·动态规划