leetcode题解-105 && 106. Construct Binary Tree from Preorder (PostOrder) and Inorder Traversal

来源:互联网 发布:吉利知豆d1续航 编辑:程序博客网 时间:2024/06/06 07:20

其实这两道题目就是从二叉树的前序遍历(后序遍历)和中序遍历数组中恢复出二叉数即可。我们知道二叉树的三种遍历方法后本题就变得很简单了。
先序遍历
若二叉树为空,则不进行任何操作:否则
1、访问根结点。
2、先序方式遍历左子树。
3、先序遍历右子树。
中序遍历
若二叉树为空,则不进行任何操作:否则
1、中序遍历左子树。
2、访问根结点。
3、中序遍历右子树。
后序遍历:
若二叉树为空,则不进行任何操作:否则
1、后序遍历左子树。
2、后序遍历右子树。
3、放问根结点。
所以当给定中序遍历和另外一种遍历方法时,我们就可以方便的结合两种遍历结果得到原始二叉树。以106题为例,题目中给出了中序遍历和后序遍历,我们首先根据后序遍历的最后一个元素确定根节点,然后再中序遍历数组中查找该元素得到其索引位置,就可以确定根节点的左右子树。然后递归调用即可。代码入下:

    public TreeNode buildTree(int[] inorder, int[] postorder) {        return build(inorder, inorder.length-1, 0, postorder, postorder.length-1);    }    public TreeNode build(int[] inorder, int inStart, int inEnd, int[] postorder, int postStart){        if(inEnd > inStart)            return null;        TreeNode root = new TreeNode(postorder[postStart]);        if(inEnd == inStart)            return root;        int index = 0;        for(int i=inStart; i>=inEnd; i--){            if(inorder[i] == root.val){                index=i;                break;            }        }        root.right = build(inorder, inStart, index+1, postorder, postStart-1);        root.left = build(inorder, index-1, inEnd, postorder, postStart-(inStart-index)-1);        return root;    }

分析上面方法,我们发现对每次递归调用时都要查询中序遍历数组中根节点所在位置,所以我们可以使用HashMap来保存中序遍历数组,这样就可以节省很多中间的查询时间。但是结果却发现,使用hashMap之后代码效率反而下降了,猜测原因可能是测试用例较小,不能体现出map的优势。代码入下:

    public TreeNode buildTree1(int[] inorder, int[] postorder) {        if (inorder == null || postorder == null || inorder.length != postorder.length)            return null;        HashMap<Integer, Integer> hm = new HashMap<Integer,Integer>();        for (int i=0;i<inorder.length;++i)            hm.put(inorder[i], i);        return buildTreePostIn(inorder, 0, inorder.length-1, postorder, 0,                postorder.length-1,hm);    }    private TreeNode buildTreePostIn(int[] inorder, int is, int ie, int[] postorder, int ps, int pe,                                     HashMap<Integer,Integer> hm){        if (ps>pe || is>ie) return null;        TreeNode root = new TreeNode(postorder[pe]);        int ri = hm.get(postorder[pe]);        root.left = buildTreePostIn(inorder, is, ri-1, postorder, ps, ps+ri-is-1, hm);        root.right = buildTreePostIn(inorder,ri+1, ie, postorder, ps+ri-is, pe-1, hm);        return root;    }

此外还可以尝试使用循环的方式来构建二叉树,代码入下:

public TreeNode buildTree(int[] inorder, int[] postorder) {    if (inorder.length == 0 || postorder.length == 0) return null;    int ip = inorder.length - 1;    int pp = postorder.length - 1;    Stack<TreeNode> stack = new Stack<TreeNode>();    TreeNode prev = null;    TreeNode root = new TreeNode(postorder[pp]);    stack.push(root);    pp--;    while (pp >= 0) {        while (!stack.isEmpty() && stack.peek().val == inorder[ip]) {            prev = stack.pop();            ip--;        }        TreeNode newNode = new TreeNode(postorder[pp]);        if (prev != null) {            prev.left = newNode;        } else if (!stack.isEmpty()) {            TreeNode currTop = stack.peek();            currTop.right = newNode;        }        stack.push(newNode);        prev = null;        pp--;    }    return root;}

那么105题就变得简单了,我们根据前序遍历和中序遍历得到原始二叉树,思路跟上面是一样的。这里就给出效率最高的方法,可以击败99。5%的用户。代码入下:

    public TreeNode buildTree1(int[] preorder, int[] inorder) {        return buildTree(preorder, 0, inorder, inorder.length - 1, 0);    }    private TreeNode buildTree(int[] preorder, int idx, int[] inorder, int end, int start) {        if (idx >= preorder.length || start > end) {            return null;        }        TreeNode root = new TreeNode(preorder[idx]);        int i;        for (i = end; i >= start; i--) {            if (preorder[idx] == inorder[i]) {                break;            }        }        root.left = buildTree(preorder, idx + 1, inorder, i - 1, start);        root.right = buildTree(preorder, idx + i - start + 1, inorder, end, i+1);        return root;    }
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 腰椎间盘膨出的原因 腰椎间盘突出初期症状 腰椎间盘突出症的锻炼 腰椎间盘突出的锻炼 腰椎间盘突出的护理 腰椎间盘突出按摩手法 腰椎间盘突出和脱出 腰椎间盘突出如何保养 腰椎间盘突出的保养 腰椎间盘突出有何症状 腰椎间盘突出医院好 得了腰椎间盘突出怎么办 腰椎间盘突出的锻炼方法 腰椎间盘为什么会突出 腰椎间盘突出要注意哪些 腰椎间盘突出吃中药 腰椎间盘突出的腰带 腰椎间盘突出按摩器 腰椎间盘突出新疗法 腰椎间盘突出费用多少 腰椎间盘突出微创多少钱 腰椎间盘突出哪里医院好 腰椎间盘突出怎样按摩 腰椎间盘突出哪个医院好 腰椎间盘突出适合什么运动 腰椎间盘突出能自愈吗 腰椎间盘突出能复位吗 腰椎间盘突出手法复位 腰椎间盘突出能做瑜伽吗 霍华德腰椎间盘突出 腰椎间盘突出拍片能看出来吗 腰椎间盘突出去那家医院好 腰椎间盘突出能用按摩器吗 腰椎间盘突出专业医院 腰椎间盘突出应该看什么科 腰椎间盘突出要住院吗 腰椎间盘突出的微创疗法 腰椎间盘滑脱是怎么回事 腰椎间盘突出康复训练 腰椎间盘突出有什么好的办法 腰椎间盘突出 哪个医院