[Una pregunta por día] Likou 103: Recorrido en secuencia en zigzag de árboles binarios (implementado por dos pilas)

Descripción del título ( portal )

Dado un árbol binario, devuelve el recorrido de la secuencia en zigzag de sus valores de nodo. (Es decir, atraviese la siguiente capa de izquierda a derecha, luego de derecha a izquierda, y así sucesivamente, alternando entre capas).

Ejemplo

Por ejemplo:
dado un árbol binario [3,9,20, null, null, 15,7],

    3
   / \
  9  20
    /  \
   15   7

Devuelve el recorrido de la secuencia en zigzag de la siguiente manera:

[
  [3],
  [20,9],
  [15,7]
]

Ideas

Se utilizan dos estructuras de pila, a saber, la pila de la izquierda primero y la pila de la derecha primero; la pila de la
izquierda primero: Tenga en cuenta que el subárbol derecho se agrega antes que el subárbol izquierdo al entrar en la pila, porque de esta manera, su orden de apilamiento es de izquierda a derecha.
La pila de la derecha es todo lo contrario: cuando ingresa a la pila, primero agrega el subárbol izquierdo y luego agrega el subárbol derecho, porque entonces su orden de apilamiento es de derecha a izquierda.

Luego agregue la raíz a la primera pila de la izquierda, que es la primera capa (atravesada de izquierda a derecha).
Al entrar en el bucle, la primera pila de la izquierda se abre y la pila de la derecha se introduce en la pila. Cuando se desapila la primera pila de la izquierda (la capa actual), la pila de la derecha primero también empuja la siguiente capa de elementos a la pila.
La primera pila de la izquierda está vacía para indicar el final de una capa, y luego la pila de la derecha primero aparece y la siguiente capa de elementos se agrega a la pila de la izquierda primero.
De esta manera, la conveniencia de zigzag se logra recorriendo las pilas de prioridad izquierda y derecha.Cuando ambas pilas están vacías, el recorrido finaliza.

Puede que esté un poco por ahí, luego mire los comentarios del código:

Código

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    
    
    public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
    
    
        List<List<Integer>> list = new ArrayList<>();
        if (root == null) {
    
    
            return list;
        }
        Deque<TreeNode>  leftstack = new LinkedList<>();// 左优先栈(先加入右子树再加入右子树)
        Deque<TreeNode> rightstack = new LinkedList<>();// 右优先栈 与上边相反
        leftstack.push(root);//先从左往右,所以root加入左优先栈
        while (!leftstack.isEmpty() || !rightstack.isEmpty()) {
    
     //只要有一个不为空说明就没有便利结束
            // 因为第一层root已经加入左优先栈,下来就给右优先栈加入左右子树。
            // 如果不为空说明还是上一层的,只有空了才能加入
            if (rightstack.isEmpty()) {
    
    
                List<Integer> tempList = new ArrayList<>();
                while (!leftstack.isEmpty()) {
    
    // 左优先(本层)不为空,向右优先(下一层)加入左右子树
                    TreeNode temp = leftstack.peek();
                    tempList.add(temp.val);
                    //在这里,左优先栈是出栈状态,右优先栈是进栈状态。这和下边的进栈顺序不同也就实现锯齿形层序遍历
                    if (temp.left != null) {
    
    
                        rightstack.push(temp.left);
                    }
                    if (temp.right != null) {
    
    
                        rightstack.push(temp.right);
                    }
                    leftstack.pop();// 左优先出栈,左优先栈循环出栈,出栈时加入每个的左右子树
                }
                list.add(tempList);// 走到这里说明左优先栈为空了,说明本层也就便利完毕,同时下一层元素也就加入了右优先栈。将本层元素加入list
            } else {
    
    
                // 与上边刚好相反
                List<Integer> tempList = new ArrayList<>();
                while (!rightstack.isEmpty()) {
    
    
                    TreeNode temp = rightstack.peek();
                    tempList.add(temp.val);
                    if (temp.right != null) {
    
    
                        leftstack.push(temp.right);
                    }
                    if (temp.left != null) {
    
    
                        leftstack.push(temp.left);

                    }
                    rightstack.pop();
                }
                list.add(tempList);
            }
        }
        //走到这里,循环结束说明两个栈内都为空了,说明二叉树遍历完毕
        return list;


    }
}

Supongo que te gusta

Origin blog.csdn.net/weixin_45532227/article/details/111538849
Recomendado
Clasificación