[LeetCode] -árbol binario-3

prefacio

Registre las preguntas relacionadas con el árbol binario encontradas en el cepillado de preguntas de LeetCode, Parte 3

1302. La suma de los nodos foliares más profundos de la capa.

Recorra el árbol binario manteniendo maxDepth, el nivel más profundo, y use res para mantener la suma numérica de los nodos en el nivel más profundo.

class Solution {
    
    
    int maxDepth;
    int res;
    public void rec(TreeNode t,int depth){
    
    
        if(t == null) return;
        //遍历到比 maxDepth 更大的层数就更新maxDepth同时重置res
        if(depth > maxDepth){
    
     
            res = t.val;
            maxDepth = depth;
        }
        else if(depth == maxDepth) res += t.val;
        rec(t.left,depth + 1);
        rec(t.right,depth + 1);
    }
    public int deepestLeavesSum(TreeNode root) {
    
    
        maxDepth = -1;
        rec(root,0);
        return res;
    }
}

404.Suma de hojas izquierdas

public int sumOfLeftLeaves(TreeNode root) {
    
    
    if(root == null) return 0;
    //如何判断左叶子,从左叶子自身并不能知道它是左叶子,
    //只能从父亲节点才能判断
    if(root.left != null && root.left.left == null && root.left.right == null){
    
    
        return root.left.val + sumOfLeftLeaves(root.right);
    }
    return sumOfLeftLeaves(root.left) + sumOfLeftLeaves(root.right);
}

114. Expandir el árbol binario a una lista vinculada

Según el recorrido de pedido previo, el nodo atravesado anteriormente se mantiene al mismo tiempo. Al atravesar el nodo actual, la derecha del nodo anterior apunta al nodo actual. Al mismo tiempo, la izquierda del nodo actual debe establecerse en nulo, y cuando se atraviesa el subárbol izquierdo, la derecha del nodo actual se modificará, por lo que los hijos izquierdo y derecho del nodo actual deben registrarse primero.

class Solution {
    
    
    TreeNode prv; //记录先序遍历时上一个访问的数
    public void flatten(TreeNode root) {
    
    
        if(root == null) return;
        if(prv != null) prv.right = root;
        prv = root;
        TreeNode l =  root.left;
        TreeNode r =  root.right;
        root.left = null;
        flatten(l);
        flatten(r);
    }
}

109. Conversión ordenada de listas enlazadas a árbol de búsqueda binaria

La secuencia numérica de la lista enlazada ordenada es en realidad la secuencia transversal en orden del árbol de búsqueda binario convertido, por lo que el árbol se puede construir en función del recorrido en orden.En el proceso, los valores de los nodos en la La lista enlazada se asigna a los nodos en orden.

El punto final de la construcción del árbol debe juzgarse de acuerdo con la longitud de la lista vinculada.

class Solution {
    
    
    ListNode list;
    public TreeNode sortedListToBST(ListNode head) {
    
    
        list = head;
        int length = getLength(head);
        return buildTree(0, length - 1);
    }
    public TreeNode buildTree(int left, int right) {
    
    
	    //当 left > right 其实就相当于遍历到了空结点,返回 null
        if (left > right) {
    
     
            return null;
        }
        //当[left,right]中只有偶数个数时,(left + right) >> 1 会取到两个中位数中偏小的那个数
        //但应该取偏大的那个数,所以要 (left + right + 1) >> 1
        //而当有奇数个数时,(left + right) >> 1 跟 (left + right + 1) >> 1是等价的
        int mid = (left + right + 1) >> 1;
        TreeNode root = new TreeNode();
        root.left = buildTree(left, mid - 1);
        root.val = list.val;
        list = list.next;
        root.right = buildTree(mid + 1, right);
        return root;
    }
    //计算原有序链表的长度
    public int getLength(ListNode head) {
    
    
        int count = 0;
        while (head != null) {
    
    
            count++;
            head = head.next;
        }
        return count;
    }
}

199.Vista derecha del árbol binario.

Sobre la base del recorrido jerárquico, cuando cada capa atraviesa hasta el último elemento, su valor se agrega a res

class Solution {
    
    
    private ArrayList<Integer> res = new ArrayList<>();
    public List<Integer> rightSideView(TreeNode root) {
    
    
        if(root != null){
    
    
            TreeNode t = root;
            LinkedList<TreeNode> queue = new LinkedList<>();
            LinkedList<TreeNode> queue1 = new LinkedList<>();
            queue.offer(t);
            while(!queue.isEmpty()){
    
    
                ArrayList<Integer> list = new ArrayList<>();
                while(!queue.isEmpty()){
    
    
                    t = queue.poll();
                    //当弹出t后栈为空,说明t是当前这一层的最后一个元素,也就是题目要的右视图在这一层的元素,所以把他的值加入res
                    if(queue.isEmpty()) res.add(t.val);
                    if(t.left != null) queue1.offer(t.left);
                    if(t.right != null) queue1.offer(t.right);
                }
                while(!queue1.isEmpty()){
    
    
                    queue.offer(queue1.poll());
                }
            }
        }
        return res;
    }
}

Durante el segundo pincel, escribí la siguiente versión de código:

public List<Integer> rightSideView(TreeNode root) {
    
    
    List<Integer> res = new ArrayList<>();
    if(root != null){
    
    
        TreeNode t = root;
        LinkedList<TreeNode> queue = new LinkedList<>();
        queue.offer(t);
        while(!queue.isEmpty()){
    
    
            int size = queue.size();
            for(int i = 0;i < size;i++){
    
    
                t = queue.poll();
                if(t.left != null) queue.offer(t.left);
                if(t.right != null) queue.offer(t.right);
            }
            res.add(t.val);
        }
    }
    return res;
}

La diferencia con la primera versión del código es que en la primera versión, para atravesar la cola sin atravesar la siguiente capa de nodos recién agregados en este recorrido, se usa una segunda cola para guardar la información de los nodos atravesados ​​en este transversal Nodos hijos, agregue esos nodos secundarios a la cola original después del final de este recorrido

La segunda versión solo cuenta el número de elementos en la cola antes de atravesar. Estos elementos son los nodos que se atravesarán esta vez. Si atraviesa de acuerdo con su número, no tendrá miedo de atravesar los nodos recién agregados.

637. Nivel promedio del árbol binario.

class Solution {
    
    
    private ArrayList<Double> res = new ArrayList<>();
    public List<Double> averageOfLevels(TreeNode root) {
    
    
        if(root != null){
    
    
            TreeNode t = root;
            LinkedList<TreeNode> queue = new LinkedList<>();
            LinkedList<TreeNode> queue1 = new LinkedList<>();
            queue.offer(t);
            while(!queue.isEmpty()){
    
    
            	//tem记录每层所有节点值之和
                Double tem = 0D;
                //count记录每层结点个数
                int count = 0;
                while(!queue.isEmpty()){
    
    
                    t = queue.poll();
                    tem += t.val;
                    count++;
                    if(t.left != null) queue1.offer(t.left);
                    if(t.right != null) queue1.offer(t.right);
                }
                //每遍历完一层计算一个平均值加入res
                res.add(tem / count);
                while(!queue1.isEmpty()){
    
    
                    queue.offer(queue1.poll());
                }
            }
        }
        return res;
    }
}

515. Encuentra el valor máximo en cada fila del árbol.

class Solution {
    
    
    ArrayList<Integer> res = new ArrayList<>();
    public List<Integer> largestValues(TreeNode root) {
    
    
        if(root != null){
    
    
            TreeNode t = root;
            LinkedList<TreeNode> queue = new LinkedList<>();
            queue.offer(t);
            while(!queue.isEmpty()){
    
    
            	//初始化最大值为最小值
                int max = Integer.MIN_VALUE;
                int count = queue.size();
                for(int i = 1;i <= count;i++){
    
    
                    t = queue.poll();
                    //如果当前节点的值大于记录的最大值那么它的值就是新的最大值
                    max = t.val > max ? t.val : max;
                    if(t.left != null) queue.offer(t.left);
                    if(t.right != null) queue.offer(t.right);
                }
                res.add(max);
            }
        }
        return res;
    }
}

116. Complete el siguiente nodo derecho de cada nodo.

class Solution {
    
    
    private ArrayList<Integer> res = new ArrayList<>();
    public Node connect(Node root) {
    
    
        if(root != null){
    
    
            Node t = root;
            Node tem = null;
            LinkedList<Node> queue = new LinkedList<>();
            queue.offer(t);
            while(!queue.isEmpty()){
    
    
                int count = queue.size();
                //先让t指向当前层次第一个结点,然后从第二个结点开始遍历,tem指向新遍历到的结点,让t的next指向tem,然后再往后移动t跟tem,相当于t为前一个结点,tem为当前结点,才可以连接起来
                t = queue.poll();
                if(t.left != null) queue.offer(t.left);
                if(t.right != null) queue.offer(t.right);
                for(int i = 2;i <= count;i++){
    
    
                    tem = queue.poll();
                    t.next = tem;
                    t = tem;
                    if(tem.left != null) queue.offer(tem.left);
                    if(tem.right != null) queue.offer(tem.right);
                }
                //从循环可以看出来遍历完最后一个结点时它的next还没设定,应该设为null
                t.next = null;
            }
        }
        return root;
    }
}

117 preguntas, misma idea, mismo código

Supongo que te gusta

Origin blog.csdn.net/Pacifica_/article/details/124509375
Recomendado
Clasificación