leetCode_105 Construye un árbol binario basado en la reserva y el recorrido de orden medio de un árbol

tema:

El árbol binario se construye de acuerdo con el orden previo y el recorrido de orden medio de un árbol.

Nota:
puede asumir que no hay elementos duplicados en el árbol.

Por ejemplo, dado

Preorder traversal preorder = [3,9,20,15,7] Inorder
traversal inorder = [9,3,15,20,7]
devuelve el siguiente árbol binario:

    3
   / \
  9 20
    / \
   15 7

Método de análisis: divide y vencerás

Combina las definiciones de "recorrido de pedido previo" y "recorrido de orden medio"

El primer nodo del recorrido de la reserva debe ser el nodo raíz del árbol binario;

El nodo raíz del recorrido en orden divide el recorrido en orden en dos partes. La parte izquierda constituye el subárbol izquierdo del nodo raíz del árbol binario y la parte derecha constituye el subárbol derecho del nodo raíz del árbol binario.

Determine 3 como el nodo raíz. De acuerdo con el recorrido en orden, puede saber que 3 es el subárbol izquierdo del nodo raíz a la izquierda y el subárbol derecho del nodo raíz a la derecha; luego, la recursividad ...

A continuación, repetiré las ideas.

Suponga que preLeft es el límite izquierdo del recorrido de preorden, preRight es el límite derecho del recorrido de preorden; inLeft es el límite izquierdo del recorrido de orden medio e inRight es el límite derecho del recorrido de orden medio.

Luego, preLeft apunta a la raíz del nodo raíz, y el límite izquierdo del subárbol izquierdo del nodo raíz es preLeft + 1. Al mismo tiempo, el nodo raíz se puede encontrar en el recorrido de orden medio. Establezca pIndex para que apunte al nodo raíz transversal de orden medio, luego el orden intermedio atraviesa el hijo izquierdo del nodo raíz medio. El intervalo del árbol es [inLeft, pIndex-1] y el intervalo del subárbol derecho es [pIndex + 1, inRight]. Lo que queda es que el preorden atraviesa el límite derecho del subárbol izquierdo y el límite izquierdo del subárbol derecho, pero la longitud del subárbol izquierdo es la misma que la longitud del recorrido de orden medio, que se puede obtener mediante la siguiente relación:

El resultado final es el siguiente

Escribir código:

    public static class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;

        TreeNode(int x) {
            val = x;
        }

    }


    public static TreeNode buildTree(int[] preorder, int[] inorder) {
        int preLen = preorder.length;//前序遍历的长度
        int inLen = inorder.length;//中序遍历的长度

        // 可以不做判断,因为题目中给出的数据都是有效的
        if (preLen != inLen) {
            return null;
        }

        // 以空间换时间,否则,找根结点在中序遍历中的位置需要遍历
        Map<Integer, Integer> map = new HashMap<>(inLen);
        for (int i = 0; i < inLen; i++) {
            map.put(inorder[i], i);
        }

        return buildTree(preorder,0, preLen - 1,map, 0, inLen - 1);
    }

    /**
     * 根据前序遍历数组的 [preL, preR] 和 中序遍历数组的 [inL, inR] 重新组建二叉树
     *
     *
     * @param preorder
     * @param preL 前序遍历数组的区间左端点
     * @param preR 前序遍历数组的区间右端点
     * @param map
     * @param inL  中序遍历数组的区间左端点
     * @param inR  中序遍历数组的区间右端点
     * @return 构建的新二叉树的根结点
     */
    private static TreeNode buildTree(int[] preorder, int preL, int preR,
                                      Map<Integer, Integer> map, int inL, int inR) {
        if (preL > preR || inL > inR) {
            return null;
        }
        // 构建的新二叉树的根结点一定是前序遍历数组的第 1 个元素
        int rootVal = preorder[preL];
        TreeNode root = new TreeNode(rootVal);

        int pIndex = map.get(rootVal );//中序遍历根节点的索引

        // 按照图中描述,计算边界的取值
        root.left = buildTree(preorder, preL + 1, preL + (pIndex - inL), map, inL, pIndex - 1);
        root.right = buildTree(preorder, preL + (pIndex - inL) + 1, preR, map, pIndex + 1, inR);
        return root;
    }

¡Esto es el fin!

 

Fuente: LeetCode
Enlace: https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal Los
derechos de autor son propiedad de LeetCode . Para reimpresiones comerciales, comuníquese con la autorización oficial. Para reimpresiones no comerciales, indique la fuente.

Supongo que te gusta

Origin blog.csdn.net/weixin_43419256/article/details/107832473
Recomendado
Clasificación