华为机试4.20:按照路径替换二叉树

这是华为第二道200分的题,考的是树的基本结构。

将一颗子二叉树按照路径替换到另一颗根二叉树中,得到一颗新的二叉树。替换动作满足如下条件:

1.子树的根节点完全替换根二叉树对应的节点

2.子树根节点下的子树完全保留

3.根二叉树的对应节点下的子树完全删除

输入

输入为3行

第一行:一个数组,表示根二叉树。二叉树的每个节点在1到9之间,包含1和9,空节点用0表示。

第二行:一个字符串,表示子二叉树根节点对应根二叉树的节点,如“/1/2”对应(每个节点下不存在相同的子节点,即path对应的子树最多只有一个):

第三行:一个数组,表示子二叉树,二叉树的每个节点在1到9之间,包含1和9,空节点用0表示。

输入限制:

1.给定的根二叉树和子叉树深度不超过5

2.给定的路径始终有效,并且会指向唯一的子二叉树,不存在子树不存在的场景。

输出

一个数组,表示一个二叉树,逐层从左到右描述,为空的节点忽略(与输入不同

样例1

输入:

[1,1,2,0,0,4,5]
/1/2
[5,3,0]

输出:

[1,1,5,3]

解释:

样例2

输入

[1,1,2,0,0,4,5]
/1/1
[5,3,0]

输出:

[1,5,2,3,4,5]

 解释:

样例3

输入

[1,1,2,0,0,4,5]
/1
[5,3,2]

输出

[5,3,2]

样例4

输入

[1,2,5,4,9,6,7,0,0,0,0,0,0,3,2]
/1/5/6
[3,5,4,2,1,0,0]

输出

[1,2,5,4,9,3,7,5,4,3,2,2,1]

思路:先建树,之后找到对应节点直接替换即可,最后进行层次遍历打印所有的值。以Java示例,

树的基本结构:

//定义二叉树的结构
    public static class Tree{
        int val;
        Tree left;
        Tree right;
        Tree(int val){
            this.val = val;
        }
    }

数组建树的代码如下:

//数组建树
    public static Tree buildTree(int array[], int index){
        Tree head= null;
        if(index<array.length){
            int cur = array[index];
            if(cur!=0) {
                head = new Tree(cur);
                head.left =  buildTree(array,2*index+1);
                head.right =  buildTree(array,2*index+2);
            }
        }
        return head;
    }

完整代码如下:

import java.util.*;



public class Solution2 {

    //定义二叉树的结构
    public static class Tree{
        int val;
        Tree left;
        Tree right;
        Tree(int val){
            this.val = val;
        }
    }

    //数组建树
    public static Tree buildTree(int array[], int index){
        Tree head= null;
        if(index<array.length){
            int cur = array[index];
            if(cur!=0) {
                head = new Tree(cur);
                head.left =  buildTree(array,2*index+1);
                head.right =  buildTree(array,2*index+2);
            }
        }
        return head;
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        //处理根二叉树
        String str1 = sc.nextLine();
        String []s1 = str1.substring(1,str1.length()-1).split(",");
        int arr1[] = new int[s1.length];
        for(int k=0;k<arr1.length;k++){
            arr1[k] = Integer.parseInt(s1[k]);
        }

        //处理路径
        String str2 = sc.nextLine();
        String[] s2 = str2.substring(1).split("/");
        int[] arr2 = new int[s2.length];
        for (int i = 0; i < s2.length; i++) {
            arr2[i] = Integer.parseInt(s2[i]);
        }

        //处理子二叉树
        String str3 = sc.nextLine();
        String []s3 = str3.substring(1,str3.length()-1).split(",");
        int arr3[] = new int[s3.length];
        for(int k=0;k<arr3.length;k++){
            arr3[k] = Integer.parseInt(s3[k]);
        }

        Tree tree = buildTree(arr1,0);
        Tree childTree = buildTree(arr3,0);
        //特殊情况,完全替换
        if(arr2.length==1){
            tree = childTree;
        }
        else {
            //遍历找到对应节点
            Tree cur = tree;
            //根节点直接匹配到
            int index = 0;
            for(int k=1; ; k++){
                if(arr1[2*index+1]==arr2[k]){
                    index = 2*index+1;
                    //最后一个节点匹配到,退出
                    if(k+1==arr2.length){
                        cur.left =childTree;
                        break;
                    }
                    cur = cur.left;
                }else if(arr1[2*index+2]==arr2[k]){
                    index = 2*index+2;
                    //最后一个节点匹配到,退出
                    if(k+1==arr2.length){
                        cur.right =childTree;
                        break;
                    }
                    cur = cur.right;
                }
            }
        }
        Queue<Tree>queue = new LinkedList<>();
        queue.add(tree);
        String res="[";
        while (!queue.isEmpty()){
            Tree node = queue.poll();
            res = res + node.val +",";
            if(node.left!=null){
                queue.add(node.left);
            }
            if(node.right!=null){
                queue.add(node.right);
            }
        }
        //去掉最后一个逗号
        res = res.substring(0, res.length()-1) + "]";
        System.out.println(res);
    }
}

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值