Nivel máximo de suma de árbol binario: ¿mejor diseño?

Me gusta la recursividad (nota, código no probado):

public static int maxLevel(BinaryTreeNode tree) {    
    ArrayList<Integer> levels = new ArrayList<Integer>();
    findLevels(tree, 0, levels);
    // now just return the index in levels with the maximal value.
    // bearing in mind that levels could be empty.
}
private static void findLevels(BinaryTreeNode tree, int level,
                                  ArrayList<Integer> levels) {
    if (tree == null) {
        return;
    }
    if (levels.length <= level) {
        levels.add(0);
    }
    levels.set(level, levels.get(level) + tree.getData());
    findLevels(tree.getLeft(), level+1, levels);
    findLevels(tree.getRight(), level+1, levels);
}

Si me sintiera realmente malvado con el recolector de basura, haría que findLevels devolviera una lista de pares (nivel, valor) y sumara esos. Sin embargo, eso tiene mucho más sentido en lenguajes co-rutinarios, sería extraño en Java.

Obviamente, puede tomar la estrategia en la función recursiva y hacerlo con una pila explícita de nodos para procesar. La diferencia clave entre mi camino y el tuyo es que el mío toma memoria proporcional a la altura del árbol; el tuyo toma memoria proporcional a su ancho.

Mirando su código, parece bastante razonable para el enfoque. Cambiaría el nombre tempLevela currentLevel, y me inclinaría a extraer el bucle interno hacia una función sumLevelque toma una cola y devuelve un int y una cola (excepto que en realidad la cola sería un argumento, porque solo puede devolver un valor, grrr). Pero parece estar bien tal como está.

Respuesta 1

Depende de cuántos nodos tengan sus árboles y qué tan profundos sean. Como está realizando una primera búsqueda amplia , sus colas ocuparán O (n) espacio de memoria, lo cual está bien para la mayoría de las aplicaciones.

La siguiente solución tiene O (l) complejidad de espacio y O (n) complejidad de tiempo ( l es la profundidad de un árbol yn número de sus vértices):

public List<Integer> levelsSum(BinaryTreeNode tree) {
    List<Integer> sums = new ArrayList<Integer>()
    levelsSum(tree, sums, 0);
    return sums;
}
protected void levelsSum(BinaryTreeNode tree, List<Integer> levelSums, int level) {
    if (tree == null)
        return;
    // add new element into the list if needed
    if (level.size() <= level)
        levelSums.add(Integer.valueOf(0));
    // add this node's value to the appropriate level
    levelSums.set(level, levelSums.get(level) + tree.getData());
    // process subtrees
    levelSum(tree.getLeft(),  levelSums, level + 1);
    levelSum(tree.getRight(), levelSums, level + 1);
}

Ahora solo llame levelsSuma un árbol y escanee la lista devuelta para encontrar el valor máximo.

Respuesta: 2

¿Estás seguro de que todos los elementos serán no negativos?

Lo haría invocable como new MaxSumLevel(root).getLevel(). De lo contrario, ¿qué harás cuando a veces tengas que devolver maxSum?

Estructuraría esto como 2 bucles anidados:

while(!mainQ.isEmpty()){
     while(!mainQ.isEmpty()){
        BinaryTreeNode head = (BinaryTreeNode) mainQ.dequeue();
        BinaryTreeNode left = head.getLeft();
        BinaryTreeNode right = head.getRight();
        if (left != null) {
            tempQ.enqueue(left);
            tempSum = tempSum + left.getData();
        }
        if (right != null) {
            tempQ.enqueue(right);
            tempSum = tempSum + right.getData();
        }
     }
     mainQ = tempQ;
     tempQ = new Queue();
     tempLevel ++;
     if (tempSum > maxVal) {
         maxVal = tempSum;
         maxlevel = tempLevel;
         tempSum = 0;
     }               

}
Respuesta: 3

Este enfoque recursivo funciona para mí:

public int findMaxSumRootLeaf(TreeNode node,int currSum) {
    if(node == null)
        return 0;
    return Math.max(findMaxSumRootLeaf(node.leftChild,currSum)+node.data, findMaxSumRootLeaf(node.rightChild,currSum)+node.data);
}
Respuesta: 4

Estoy tratando de configurar las bibliotecas Scichart usando esta guía. La biblioteca que descargué tiene una estructura similar a esta: copié los 5 archivos .aar y los 4 archivos .jar de documentación en las bibliotecas ...

En este hilo, he encontrado una manera de implementar la función Autocompletar en un JTextField (y JComboBox, pero no hay problema con esto). Al intentar implementar esta función en un JTextField, arroja algunos ...

Estoy tratando de entender el concepto de operadores de turno y estaba probando el siguiente código: 15 >> 2; - 15 >> 2 El resultado del primer enunciado es 3 como 15/4 = 3 pero el ...

Hola, estoy tratando de abrir el archivo de Word usando el programa Java. El programa me da el siguiente error "No se puede hacer una referencia estática al método abierto (Archivo) no estático desde el tipo Escritorio No sé cómo ...