题解 | #重建二叉树#

重建二叉树

http://www.nowcoder.com/practice/8a19cbe657394eeaac2f6ea9b0f6fcf6

描述

给定节点数为 n 的二叉树的前序遍历和中序遍历结果,请重建出该二叉树并返回它的头结点。 例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建出如下图所示。

alt

思路1:递归+分治

  • 前序遍历:根左右
  • 中序遍历:左根右
  1. 前序遍历第一个元素为根节点,即1
  2. 在中序遍历序列中找到对应的元素1
  3. 此时左半部分为左子树{4,7,2},对应的前序遍历序列为{2,4,7}。
  4. 右半部分为右子树{5,3,8,6},对应的前序遍历序列为{3,5,6,8}。
  5. 用同样的方法找到左子树的根节点为2,右子树的根节点为3。分别作为1的子节点{1,2,3}
  6. 不断分解,直到子树长度为0
public class Solution {
    public TreeNode reConstructBinaryTree(int [] pre,int [] vin) {
        int len = pre.length;
        if(len == 0) {
            return null;
        }
        TreeNode root = new TreeNode(pre[0]);
        for(int i = 0; i < len; i++) {
            if(root.val == vin[i]) {
                //左半部分
                int[] leftPre = Arrays.copyOfRange(pre, 1, i + 1);
                int[] leftVin = Arrays.copyOfRange(vin, 0, i);
                root.left = reConstructBinaryTree(leftPre, leftVin);
                //右半部分
                int[] rightPre = Arrays.copyOfRange(pre, i + 1, len);
                int[] rightVin = Arrays.copyOfRange(vin, i + 1, len);
                root.right = reConstructBinaryTree(rightPre, rightVin);
                break;
            }
        }
        return root;
    }
}

思路2:使用栈

前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6}

遍历前序序列,下一个节点要么是左节点,要么是右节点或者其祖先的右节点

public class Solution {
    public TreeNode reConstructBinaryTree(int [] pre,int [] vin) {
        int len = pre.length;
        if(len == 0) {
            return null;
        }
        TreeNode ret = new TreeNode(pre[0]);
        Stack<TreeNode> stack = new Stack<>();
        TreeNode cur = ret;
        int j = 0;
        for(int i = 1; i < len; i++) {
            if(cur.val != vin[j]) {
                // 到达最左端
                cur.left = new TreeNode(pre[i]);
                stack.push(cur);
                cur = cur.left;
            } else {
                j++;
                // 找到合适的祖先
                while(!stack.isEmpty() && stack.peek().val == vin[j]) {
                    cur = stack.pop();
                    j++;
                }
                cur.right = new TreeNode(pre[i]);
                cur = cur.right;
            }
        }
        return ret;
    }
}
全部评论

相关推荐

10-30 19:23
已编辑
山东大学(威海) C++
牛至超人:其实简历是不需要事无巨细的写的,让对方知道你有这段经历就行了,最重要的是面试的时候讲细讲明白
点赞 评论 收藏
分享
已经入职数字马力4个月了,忍不住想和大家聊聊最真实的感受!🔥1️⃣&nbsp;岗位偏见?作为蚂蚁的子公司,很多人会担心“内包”身份会不会有岗位偏见。就我这几个月的体验来说,数字马力一直在快速扩招,面试流程也越来越规范(尤其是校招环节)。至于偏见问题,真的看部门和leader,很幸运我遇到的师兄和主管都特别nice,团队氛围很融洽。2️⃣&nbsp;待遇怎么样?试用期工资不打折!这点我真的吹爆💥!每天六点下班还有餐补,公积金按全额8%交(感动哭)……不过养老金也是实打实的8%,到手稍微心疼一下下😂3️⃣&nbsp;技术栈跟得上吗?技术栈多到学不完……而且我们有权限访问蚂蚁的知识库,自学能力强+愿意钻研的话,成长速度真的飞快!(当然,像我这种偶尔偷懒的也在慢慢进步中😝)4️⃣&nbsp;面试流程?一般是三面:两轮技术面(可能有线上笔试)+&nbsp;一轮HR面(含背调)。整体节奏比较顺畅,反馈也及时。5️⃣&nbsp;未来发展怎么看?老实说,数字马力不算头部大厂,不能指望它给简历镀金,但也绝不是那种会“减分”的外包。我更愿意把它看作一个扎实的中厂跳板,适合积累实战经验。6️⃣&nbsp;怎么投递?通过数字马力gzh,今天刚放出一批新HC!如果你正在看机会,不妨试试数字马力~之前面挂过也没关系,不妨再战一次,机会说不定就来了!🤝✅&nbsp;我的专属内推码:NTA6Nvs,可以直接帮大家推进流程。📮&nbsp;有任何关于公司、岗位、面试的问题,也欢迎留言,我会尽量回复~(小声说:大环境不易,希望大家都能找到心仪的工作,也欢迎来找我内推呀!)
数字马力公司福利 22人发布
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务