剑指 Offer 07. 重建二叉树

剑指 Offer 07. 重建二叉树

 

剑指 Offer 07. 重建二叉树_第1张图片

【分治】由前序和中序是可以还原二叉树结构的:

前序:根|左|右

中序:左|根|右

所以,前序的第一个为根,然后在中序中找到根,就可以分成左右子树了,接下来根据中序中根到最左边元素的个数,又可以把前序也分成左右子树,然后递归传入即可。

以样例一为:

pre:3,9,20,25,7

in :9,3,15,20,7

先从pre中确定第一个根是3,然后从in中定位到3在第二个,所以左边的9就属于左子树,右边[15,20,7]属于右子树,左边共一个元素;然后回到pre来确定这个序列的左右子树,3往右数一个是左子树,剩下的是右子树。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {

    int[] pre, in;
    Map map = new HashMap(); 

    public TreeNode dfs(int preleft, int preright, int inleft, int inright){
        if(preleft > preright) return null;
        if(preleft == preright) return new TreeNode(pre[preleft]);
        TreeNode root = new TreeNode(pre[preleft]);
        // 3 9 20 15 7
        // 9 3 15 20 7        
        int idx = map.get(pre[preleft]);
        int num = idx - inleft;
        root.left = dfs(preleft + 1, preleft + num, inleft, idx - 1);
        root.right = dfs(preleft + num + 1, preright, idx + 1, inright);
        return root;
    }

    public TreeNode buildTree(int[] preorder, int[] inorder) {
        pre = preorder;
        in = inorder;
        int n = inorder.length;
        for(int i = 0; i < n; i++) map.put(in[i], i);
        return dfs(0, n - 1, 0, n - 1);
    }
}

你可能感兴趣的:(剑指offer,leetcode,分治,二叉树)