二叉树系统刷题1

文章目录

    • **BM26** **求二叉树的层序遍历**
    • **BM27** **按之字形顺序打印二叉树**
    • **BM28** **二叉树的最大深度**
    • **BM29** **二叉树中和为某一值的路径(一)**
    • **BM30** **二叉搜索树与双向链表**
    • **BM31** **对称的二叉树**
    • **BM32** **合并二叉树**
    • **BM34** **判断是不是二叉搜索树**
    • **BM35** **判断是不是完全二叉树**
    • **BM36** **判断是不是平衡二叉树**
    • **BM37** **二叉搜索树的最近公共祖先**
    • **BM38** **在二叉树中找到两个节点的最近公共祖先**
    • **BM39** **序列化二叉树**
    • **BM40** **重建二叉树**
    • **BM41** **输出二叉树的右视图**

BM26 求二叉树的层序遍历

请添加图片描述

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 * }
 */

public class Solution {
    /**
     *
     * @param root TreeNode类
     * @return int整型ArrayList<ArrayList<>>
     */
    public ArrayList<ArrayList<Integer>> levelOrder (TreeNode root) {
        // write code here
        ArrayList<ArrayList<Integer>> res = new ArrayList();
        if (root == null) return res;
        //使用队列存储,进行层序遍历
        Queue<TreeNode> q = new ArrayDeque<TreeNode>();
        q.add(root);//将root插入到队列的末尾
        while (!q.isEmpty()) {
            //记录二叉树的某一行
            ArrayList<Integer> row = new ArrayList();
            int n = q.size();
            //因先进入队列的是根节点,故每层节点多少,队列大小就是多少
            for (int i = 0; i < n; i++) {
                TreeNode cur = q.poll(); //出,同时记录cur节点
                row.add(cur.val);
                //若左右孩子存在,则存入左右孩子作为下一次层次
                if (cur.left != null) q.add(cur.left);
                if (cur.right != null) q.add(cur.right);
            }
            //每一层加入
            res.add(row);
        }
        return res;
    }
}

BM27 按之字形顺序打印二叉树

请添加图片描述

import java.util.ArrayList;
import java.util.Queue;
import java.util.ArrayDeque;
import java.util.Collections;
/*
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}
*/
public class Solution {
    public ArrayList<ArrayList<Integer>> Print(TreeNode pRoot) {
        ArrayList<ArrayList<Integer>> res = new ArrayList<>();
        if (pRoot == null) return res;
        //使用队列存储,进行层序遍历
        Queue<TreeNode> q = new ArrayDeque<TreeNode>();

        q.add(pRoot);//先将头节点放入
        boolean flag = false;
        while (!q.isEmpty()) {
            ArrayList<Integer> row = new ArrayList<>();
            int n = q.size();

            for (int i = 0; i < n; i++) {
                TreeNode cur = q.poll();//弹出q,并记录
                row.add(cur.val);//存入值

                //看是否有左右还在
                if (cur.left != null) q.add(cur.left);
                if (cur.right != null) q.add(cur.right);
            }
            //要实现奇数层从左到由,偶数层从右到左,即偶数时要逆序q队列
            if (flag) Collections.reverse(row);
            flag = !flag;
            res.add(row);
        }
        return res;
    }

}

BM28 二叉树的最大深度

在这里插入图片描述

层序法 空间复杂度O(1),时间复杂度 O*(*n)

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 * }
 */

public class Solution {
    /**
     *
     * @param root TreeNode类
     * @return int整型
     */
    public int maxDepth (TreeNode root) {
        // write code here

        if (root == null) return 0;
        //使用队列存储,进行层序遍历
        Queue<TreeNode> q = new ArrayDeque<TreeNode>();
        q.add(root);//将root插入到队列的末尾
        int h = 0;
        while (!q.isEmpty()) {
            //记录二叉树的某一行
            ArrayList<Integer> row = new ArrayList();
            int n = q.size();
            //因先进入队列的是根节点,故每层节点多少,队列大小就是多少
            for (int i = 0; i < n; i++) {
                TreeNode cur = q.poll(); //出,同时记录cur节点
                row.add(cur.val);
                //若左右孩子存在,则存入左右孩子作为下一次层次
                if (cur.left != null) q.add(cur.left);
                if (cur.right != null) q.add(cur.right);
            }
            h++;
        }
        return h;
    }
}

递归法 O(2^h)

  public int maxDepth (TreeNode root) {
        //使用递归法则需要,分别计算左右子数中最高的值
        if (root == null) return 0;
        int leftH =  maxDepth(root.left);
        int rightH = maxDepth(root.right);
        return leftH > rightH ? (leftH + 1) : (rightH + 1);
    }	

BM29 二叉树中和为某一值的路径(一)

在这里插入图片描述

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 * }
 */

public class Solution {
    /**
     *
     * @param root TreeNode类
     * @param sum int整型
     * @return bool布尔型
     */
    public boolean hasPathSum (TreeNode root, int sum) {
        // write code here
        // //执行思路,使用dfs遍历每个,同时变化sum,找到满足的值就返回真
        // if(root == null) return false;
        // //叶子路径,且路径和为sum
        // if(root.left==null&&root.right==null&&sum-root.val == 0){
        //     return true;
        // }
        // //递归进去子节点
        // return hasPathSum(root.left,sum-root.val)||hasPathSum(root.right,sum-root.val);
        if (root == null) return false;
        return dfs(root, sum, 0);// 深度优先遍历
    }

    private boolean dfs(TreeNode root, int sum, int res) {
        if (root == null) return false;
        //迭代目标值
        res += root.val;
        // 当当前节点为叶子节点并且目标路径存在时,返回 true
        if (res == sum && root.left == null && root.right == null) {
            return true;
        }
        // 对左右分支进行 dfs
        return dfs(root.left, sum, res) || dfs(root.right, sum, res);
    }
}

BM30 二叉搜索树与双向链表

在这里插入图片描述

二叉搜索树是一种特殊的二叉树,它的每个节点值大于它的左子节点,且大于全部左子树的节点值,小于它右子节点,且小于全部右子树的节点值。因此二叉搜索树一定程度上算是一种排序结构。

思路:

二叉搜索树最左端的元素一定最小,最右端的元素一定最大,符合“左中右”的特性,因此二叉搜索树的中序遍历就是一个递增序列,我们只要对它中序遍历就可以组装称为递增双向链表。

具体做法:

  • step 1:创建两个指针,一个指向题目中要求的链表头(head),一个指向当前遍历的前一节点(pre)。
  • step 2:首先递归到最左,初始化head与pre。
  • step 3:然后处理中间根节点,依次连接pre与当前节点,连接后更新pre为当前节点。
  • step 4:最后递归进入右子树,继续处理。
  • step 5:递归出口即是节点为空则返回。

在这里插入图片描述

/**
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}
*/
public class Solution {
    //返回第一个指针,即最小值,先定为null
    public TreeNode head = null;
    //中序遍历当前值的上一位,初值为最小值,先定为null
    public TreeNode pre = null;
    public TreeNode Convert(TreeNode pRootOfTree) {
        if (pRootOfTree == null) {
            //中序递归,叶子为空则返回
            return null;
        }
        //首先递归到最左最小值
        Convert(pRootOfTree.left); //左

        //中
        //找到最小值,初始化head和pre;
        if (pre == null) {
            head = pRootOfTree;
            pre = pRootOfTree;
        } else {
            //当前节点与上一结点建立连接,将pre设置为当前值
            pre.right = pRootOfTree;
            pRootOfTree.left = pre;
            pre = pRootOfTree;
        }

        Convert(pRootOfTree.right); //右
        return head;

    }
}

BM31 对称的二叉树

思路:

前序遍历的时候我们采用的是“根左右”的遍历次序,如果这棵二叉树是对称的,即相应的左右节点交换位置完全没有问题,那我们是不是可以尝试“根右左”遍历,按照轴对称图像的性质,这两种次序的遍历结果应该是一样的。

不同的方式遍历两次,将结果拿出来比较看起来是一种可行的方法,但也仅仅可行,太过于麻烦。我们不如在遍历的过程就结果比较了。而遍历方式依据前序递归可以使用递归:

  • 终止条件: 当进入子问题的两个节点都为空,说明都到了叶子节点,且是同步的,因此结束本次子问题,返回true;当进入子问题的两个节点只有一个为空,或是元素值不相等,说明这里的对称不匹配,同样结束本次子问题,返回false。
  • 返回值: 每一级将子问题是否匹配的结果往上传递。
  • 本级任务: 每个子问题,需要按照上述思路,“根左右”走左边的时候“根右左”走右边,“根左右”走右边的时候“根右左”走左边,一起进入子问题,需要两边都是匹配才能对称。

具体做法:

  • step 1:两种方向的前序遍历,同步过程中的当前两个节点,同为空,属于对称的范畴。
  • step 2:当前两个节点只有一个为空或者节点值不相等,已经不是对称的二叉树了。
  • step 3:第一个节点的左子树与第二个节点的右子树同步递归对比,第一个节点的右子树与第二个节点的左子树同步递归比较。

在这里插入图片描述

/*
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}
*/
public class Solution {
    boolean isSymmetrical(TreeNode pRoot) {
        return recursion(pRoot, pRoot);
    } 
    public boolean recursion(TreeNode root1, TreeNode root2) {
        //可以两个都为空
        if (root1 == null && root2 == null)
            return true;
        //只有一个为空或者节点值不同,必定不对称
        if (root1 == null || root2 == null || root1.val != root2.val)
            return false;
        //每层对应的节点进入递归比较
        return recursion(root1.left, root2.right) && recursion(root1.right, root2.left);
    }
}

BM32 合并二叉树

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 * }
 */

public class Solution {
    /**
     *
     * @param t1 TreeNode类
     * @param t2 TreeNode类
     * @return TreeNode类
     */
    public TreeNode mergeTrees (TreeNode t1, TreeNode t2) {
        // write code here
        //思路:同时遍历左右,相同就加上,为空就指向
        if (t1 == null) return t2;
        if (t2 == null) return t1;
        //根左右遍历
        TreeNode head = new TreeNode(t1.val + t2.val);
        head.left = mergeTrees(t1.left, t2.left);
        head.right = mergeTrees(t1.right, t2.right);
        return head;
    }
}

BM34 判断是不是二叉搜索树

思路:

二叉搜索树的特性就是中序遍历是递增序。既然是判断是否是二叉搜索树,那我们可以使用中序递归遍历。只要之前的节点是二叉树搜索树,那么如果当前的节点小于上一个节点值那么就可以向下判断。只不过在过程中我们要求反退出。比如一个链表1->2->3->4,只要for循环遍历如果中间有不是递增的直接返回false即可。

if(root.val < pre)
    return false;

具体做法:

  • step 1:首先递归到最左,初始化maxLeft与pre。
  • step 2:然后往后遍历整棵树,依次连接pre与当前节点,并更新pre。
  • step 3:左子树如果不是二叉搜索树返回false。
  • step 4:判断当前节点是不是小于前置节点,更新前置节点。
  • step 5:最后由右子树的后面节点决定。
import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    int pre = Integer.MIN_VALUE;
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param root TreeNode类 
     * @return bool布尔型
     */
    public boolean isValidBST (TreeNode root) {
        // write code here
        //中序遍历
        if(root ==  null) return true;
        //先进入左子树
        if(!isValidBST(root.left)){
            return false;
        }
        if(root.val<pre){
            return false;
        }
        //更新最值
        pre = root.val;
        //在进入右子树
        return isValidBST(root.right);
        
    }
}

BM35 判断是不是完全二叉树

思路:

对完全二叉树最重要的定义就是叶子节点只能出现在最下层和次下层,所以我们想到可以使用队列辅助进行层次遍历——从上到下遍历所有层,每层从左到右,只有次下层和最下层才有叶子节点,其他层出现叶子节点就意味着不是完全二叉树。

具体做法:

  • step 1:先判断空树一定是完全二叉树。
  • step 2:初始化一个队列辅助层次遍历,将根节点加入。
  • step 3:逐渐从队列中弹出元素访问节点,如果遇到某个节点为空,进行标记,代表到了完全二叉树的最下层,若是后续还有访问,则说明提前出现了叶子节点,不符合完全二叉树的性质。
  • step 4:否则,继续加入左右子节点进入队列排队,等待访问。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PlMO085A-1679386637750)(C:\Users\jquery\Desktop\国密算法\八股文\assets\07986E476EB2CECD3C5F81D0BCADBE12.gif)]

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param root TreeNode类 
     * @return bool布尔型
     */
    public boolean isCompleteTree (TreeNode root) {
        // write code here
        //左右都为null
        
        //空树一定为完全二叉树
        if(root == null) return true;
        //辅助队列
        Queue<TreeNode> q = new LinkedList<>();
        q.add(root);

        //定义一个首次出现的标记位
        boolean notComplete = false;
        while(!q.isEmpty()){
            TreeNode cur = q.poll();
            if(cur == null){
                //标记第一次遇到空节点
                notComplete = true;
                continue;
            }
            //后续访问以及已经遇到空节点了,说明经过了叶子
            if(notComplete) return false;
            q.add(cur.left);
            q.add(cur.right);
        }
        return true;
    }
}

BM36 判断是不是平衡二叉树

在这里插入图片描述

public class Solution {
    public boolean IsBalanced_Solution(TreeNode root) {
        //空树为平衡树
        if (root == null) return true;
        int left = deep(root.left);
        int right = deep(root.right);
        //左子树深度减去右子树相差绝对值大于1
        if (left - right > 1 || left - right < -1) {
            return false;
        }
        //同时左右子树还必须是平衡的
        return IsBalanced_Solution(root.left) && IsBalanced_Solution(root.right);
    }

    private int deep(TreeNode root) {
        //空节点深度为0
        if (root == null) return 0;

        //递归计算左右子树的深度
        int left = deep(root.left);
        int right = deep(root.right);

        //子树最大深度加上自己
        return (left > right) ? left + 1 : right + 1;
    }
}

BM37 二叉搜索树的最近公共祖先

思路:

二叉搜索树没有相同值的节点,因此分别从根节点往下利用二叉搜索树较大的数在右子树,较小的数在左子树,可以轻松找到p、q:

//节点值都不同,可以直接用值比较
while(node.val != target) { 
    path.add(node.val);
    //小的在左子树
    if(target < node.val) 
        node = node.left;
    //大的在右子树
    else 
        node = node.right;
}

直接得到从根节点到两个目标节点的路径,这样我们利用路径比较就可以找到最近公共祖先。

具体做法:

  • step 1:根据二叉搜索树的性质,从根节点开始查找目标节点,当前节点比目标小则进入右子树,当前节点比目标大则进入左子树,直到找到目标节点。这个过程成用数组记录遇到的元素。
  • step 2:分别在搜索二叉树中找到p和q两个点,并记录各自的路径为数组。
  • step 3:同时遍历两个数组,比较元素值,最后一个相等的元素就是最近的公共祖先。

在这里插入图片描述

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param root TreeNode类
     * @param p int整型
     * @param q int整型
     * @return int整型
     */
    public int lowestCommonAncestor (TreeNode root, int p, int q) {
        // write code here
        //求根节点到两个节点的路径
        ArrayList<Integer> path_p = getPasth(root, p);
        ArrayList<Integer> path_q = getPasth(root, q);

        int res = 0;
        //比较元素值,最后一个相等的元素就是最近的公共祖先。
        for (int i = 0; i < path_p.size() && i < path_q.size(); i++) {
            int x = path_p.get(i);
            int y = path_q.get(i);
            //最后一个相同的节点就是最近公共祖先
            if (x == y) {
                res = path_p.get(i);
            } else {
                break;
            }

        }
        return res;
    }

    //求得根节点到目标节点的路径
    public ArrayList<Integer> getPasth(TreeNode root, int target) {
        ArrayList<Integer> path = new ArrayList<Integer>();
        TreeNode node = root;
        //节点值都不同,可以直接比较
        while (node.val != target) {
            path.add(node.val);
            //小的在左子树
            if (target < node.val) {
                node = node.left;
            } else {
                //大的在右子树
                node = node.right;
            }

        }
        path.add(node.val);
        return path;
    }
}

BM38 在二叉树中找到两个节点的最近公共祖先

在这里插入图片描述

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 * }
 */

public class Solution {
    /**
     *
     * @param root TreeNode类
     * @param o1 int整型
     * @param o2 int整型
     * @return int整型
     */
    public int lowestCommonAncestor (TreeNode root, int o1, int o2) {
        // write code here
        ArrayList<Integer> path1 = new ArrayList<>();
        ArrayList<Integer> path2 = new ArrayList<>();
        //求根节点到两个节点的路径
        dfs(root,path1,o1);
        //重置
        flag = false;
        dfs(root,path2,o2);
        int res=0;
        //比较两个路径,找到第一个不同的点
        for(int i=0;i<path1.size()&&i<path2.size();i++){
            int x = path1.get(i);
            int y = path2.get(i);
            if(x==y){
                //最后一个相同的节点就是最近公共祖先
                res = x;
            }else{
                break;
            }
        }
        return res;
    }
    //记录是否找到到o的路径
    public boolean flag = false;
    //求得根节点到目标节点的路径
    public void dfs(TreeNode root, ArrayList<Integer> path, int o) {
        if (flag || root == null) {
            return;
        }
        path.add(root.val);
        //节点不同值都不同,可以直接用值比较
        if (root.val == o) {
            flag = true;
            return;
        }
        //dfs 遍历查找
        dfs(root.left, path, o);
        dfs(root.right, path, o);
        if (flag) return;
        path.remove(path.size() - 1);
    }
}

BM39 序列化二叉树

/*
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}
*/

import java.util.*;

public class Solution {
    String SEP = ",";
    String NULL = "#";
    String Serialize(TreeNode root) {
        StringBuilder sb = new StringBuilder();
        serialize(root, sb);
        return sb.toString();
    }
    //辅助函数,将二叉树存入StringBuilder中
    void serialize(TreeNode root, StringBuilder sb) {
        if(root == null){
            sb.append(NULL).append(SEP);
            return;
        }
        //前序遍历位置
        sb.append(root.val).append(SEP);

        serialize(root.left,sb);
        serialize(root.right,sb);
    }

    TreeNode Deserialize(String str) {
        //将字符串转成列表
        LinkedList<String> nodes = new LinkedList<>();
        for(String s:str.split(SEP)){
            nodes.addLast(s);
        }
        return deserialize(nodes);

    }

    TreeNode deserialize( LinkedList<String> nodes){
        if(nodes.isEmpty()) return null;
        //前序遍历位置,列表最左侧就是和根节点
        String first = nodes.removeFirst();
        if(first.equals(NULL)) return null;
        TreeNode root = new TreeNode(Integer.parseInt(first));
        root.left = deserialize(nodes);
        root.right =deserialize(nodes);

        return root;
    }
}

BM40 重建二叉树

在这里插入图片描述

import java.util.*;
/**
 * Definition for binary tree
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public TreeNode reConstructBinaryTree(int [] pre, int [] vin) {
        int n = pre.length;
        int m = vin.length;
        //每个遍历都不能为0
        if (n == 0 || m == 0) {
            return null;
        }
        //构建根节点 根节点必定在pre中选
        TreeNode root = new TreeNode(pre[0]);
        for (int i = 0; i < n; i++) {
            //找到中序遍历中的前序第一个元素,依据它划分左右子树
            if (pre[0] == vin[i]) {
                //构建左子树
                root.left = reConstructBinaryTree(Arrays.copyOfRange(pre,1,i+1),Arrays.copyOfRange(vin,0,i));
                //构建右子树
                root.right = reConstructBinaryTree(Arrays.copyOfRange(pre,i+1,pre.length),Arrays.copyOfRange(vin,i+1,vin.length));
                break;
            }
        }
        return root;
    }
}

BM41 输出二叉树的右视图

在这里插入图片描述

思路:

首先根据前序遍历和中序遍历生成二叉树

然后使用层序遍历得到每一层的一个数组

针对每一层的数组,取最后一个数,即可完成

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 求二叉树的右视图
     * @param xianxu int整型一维数组 先序遍历
     * @param zhongxu int整型一维数组 中序遍历
     * @return int整型一维数组
     */

    public int[] solve (int[] xianxu, int[] zhongxu) {
        TreeNode root = reConstructBinaryTree(xianxu, zhongxu);
        ArrayList<ArrayList<Integer>> res = getLevelList(root);
        ArrayList<Integer> list = new ArrayList<>();
        //将二叉树 层次便利的 每层的额最后一个 值存入新的 ArrayList 中 转化为 数组
        for (int i = 0; i < res.size(); i++) {
            list.add(res.get(i).get(res.get(i).size() - 1));
        }
        // int arr[] = new int[list.size()];
        // for (int i = 0; i < list.size(); i++) {
        //     arr[i] = list.get(i);
        // }
        int arr[] = list.stream().mapToInt(Integer::valueOf).toArray();
        return arr;
    }

    public TreeNode reConstructBinaryTree(int[] pre, int[] vin) {
        int n = pre.length;
        int m = vin.length;
        //每个遍历都不能为0
        if (n == 0 || m == 0) return null;

        //构建根节点,根节点必定在pre中选\
        TreeNode root = new TreeNode(pre[0]);
        for (int i = 0; i < n; i++) {
            //找到中序遍历中的前序第一个元素,依据它划分左右子树
            if (pre[0] == vin[i]) {
                //构建左子树
                root.left = reConstructBinaryTree(Arrays.copyOfRange(pre, 1, i + 1),
                                                  Arrays.copyOfRange(vin, 0, i));
                //构建右子树
                root.right = reConstructBinaryTree(Arrays.copyOfRange(pre, i + 1, pre.length),
                                                   Arrays.copyOfRange(vin, i + 1, vin.length));
                break;
            }
        }
        return root;
    }

    //此方法用来 二叉树的 层次遍历到 ArrayList<ArrayList<Integer>>中
    private  ArrayList<ArrayList<Integer>> getLevelList(TreeNode root) {
        ArrayList<ArrayList<Integer>> result = new ArrayList<>();
        Queue<TreeNode> q = new LinkedList<>();
        q.add(root);
        while (!q.isEmpty()) {
            ArrayList<Integer> row = new ArrayList<>();
            int n = q.size();
            for (int i = 0; i < n; i++) {
                TreeNode cur = q.poll();
                row.add(cur.val);
                if (cur.left != null) q.add(cur.left); //是cur,不是root
                if (cur.right != null) q.add(cur.right);//是cur,不是root
            }
            result.add(row);
        }
        return result;
    }

    
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/1974.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【数据结构】KMP算法细节详解

KMP算法细节详解前言一、字符串匹配问题1.BF算法2.KMP算法二、next数组三、手写nex思想四、机算next思想五、next数组细节理解六、nextVal数组七、KMP算法代码实现八、nextVal数组代码实现完结前言 KMP算法是为了字符串匹配问题而被研究出来的&#xff0c;字符串匹配问题就是查…

真实的软件测试日常工作是咋样的?

最近很多粉丝问我&#xff0c;小姐姐&#xff0c;现在大环境不景气&#xff0c;传统行业不好做了&#xff0c;想转行软件测试&#xff0c;想知道软件测试日常工作是咋样的&#xff1f;平常的工作内容是什么&#xff1f; 别急&#xff0c;今天跟大家细细说一下一个合格的软件测…

【LeetCode每日一题】——面试题17.21.直方图的水量

文章目录一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【解题思路】七【时间频度】八【代码实现】九【提交结果】一【题目类别】 双指针 二【题目难度】 困难 三【题目编号】 面试题17.21.直方图的水量 四【题目描述】 给定一个直方图(也称…

Android Studio 中使用 Gradle 配置多渠道打包 配置不同的渠道名称 配置不同的App名称 配置不同的Logo

废话三种操作都是可以混合一起用的&#xff0c;本来也不是很难的事情&#xff0c;为了方便分别理解&#xff0c;这里我就分开处理了。如果需要将打包出来的apk的名称自动命名成指定格式&#xff0c;也可以进行配置&#xff0c;我这里没这个需求&#xff0c;所以这里就不讨论了。…

晶晨S905D3切换到外部phy方法

文章目录 前言一、s905d3的以太网驱动的理解二、修改设备树注意前言 随着芯片的国产化推荐,越来越多的国产芯片被大家重视起来,但是国产的一些稍微高性能的芯片资料太少,这里把调实phy的流程记录一下,不做太多的理论分析 一、s905d3的以太网驱动的理解 如果拿到sdk后,默…

ESP32设备驱动-ADXL335加速计驱动

ADXL335加速计驱动 文章目录 ADXL335加速计驱动1、ADXL335介绍2、硬件准备3、软件准备4、驱动实现1、ADXL335介绍 ADXL335 是一款小型、薄型、低功耗、完整的 3 轴加速度计,具有信号调理电压输出。 该产品以 3 g 的最小满量程测量加速度。它可以测量倾斜传感应用中的静态重力…

JAVASE/封装、继承、多态

博客制作不易&#xff0c;欢迎各位点赞&#x1f44d;收藏⭐关注前言在学习面向对象编程语言时&#xff0c;封装、继承、多态则是我们必须学习和使用的三大特征。本文通过举例&#xff0c;说明了该三大特征的基本权限特点。一、访问限定符范围private默认权限protectedpublic同一…

springcloud3 nacos,sentinel,ribbon,openfegin等整合案例4[fallback+blockhandler完美整合]

一 说明 1.1 结论 SentinelResource(value "fb",fallback "handlerFallback") //fallback只负责业务异常 SentinelResource(value "fb",blockHandler "blockHandler") //blockHandler只负责sentinel控制台配置违规 假设fallbac…

国内版的ChatGPT弯道超车的机会在哪里?

前言 从去年11月最后一天ChatGPT诞生&#xff0c;截至目前&#xff0c;ChatGPT的热度可谓是爆了。众所周知&#xff0c;ChatGPT是美国“开放人工智能研究中心”研发的聊天机器人程序&#xff0c;它是一个人工智能技术驱动的自然语言处理工具&#xff0c;它能够通过学习和理解人…

Android性能优化的底层逻辑

前言 性能优化仿佛成了每个程序员开发的必经之路&#xff0c;要想出人头地&#xff0c;与众不同&#xff0c;你还真需要下点功夫去研究Android的性能优化&#xff0c;比如说&#xff0c;从优化应用启动、UI加载、再到内存、CPU、GPU、IO、还有耗电等等&#xff0c;当你展开一个…

Docker部署springcloud项目(清晰明了)

概述 最近在想做个cloud项目,gitee上找了个模板项目&#xff0c;后端使用到 Nacos、Gateway、Security等技术&#xff0c;需要到 Docker 容器部署&#xff0c;在此总结一下&#xff0c;若有不足之处&#xff0c;望大佬们可以指出。 什么是 Docker Docker 使用 Google 公司推…

【8】核心易中期刊推荐——人工智能与机器人

🚀🚀🚀NEW!!!核心易中期刊推荐栏目来啦 ~ 📚🍀 核心期刊在国内的应用范围非常广,核心期刊发表论文是国内很多作者晋升的硬性要求,并且在国内属于顶尖论文发表,具有很高的学术价值。在中文核心目录体系中,权威代表有CSSCI、CSCD和北大核心。其中,中文期刊的数…

【C++】Google编码风格学习

Google规范线上地址&#xff1a;https://zh-google-styleguide.readthedocs.io/en/latest/ 文章目录1. 头文件2. 作用域3. 类4. 函数5. 其他C特性6. 命名约定7. 注释8. 格式1. 头文件 每个cpp/cc文件都对应一个h头文件&#xff0c;除单元测试代码和只包含main()的文件外。 所…

100天精通Python(可视化篇)——第80天:matplotlib绘制不同种类炫酷柱状图代码实战(簇状、堆积、横向、百分比、3D柱状图)

文章目录0. 专栏导读1. 普通柱状图2. 簇状柱形图3. 堆积柱形图4. 横向柱状图5. 横向双向柱状图6. 百分比堆积柱形图7. 3D柱形图8. 3D堆积柱形图9. 3D百分比堆积柱形图0. 专栏导读 &#x1f3c6;&#x1f3c6;作者介绍&#xff1a;Python领域优质创作者、CSDN/华为云/阿里云/掘金…

Python读写EXCEL文件常用方法大全

python读写excel的方式有很多&#xff0c;不同的模块在读写的讲法上稍有区别&#xff0c;这里我主要介绍几个常用的方式。 用xlrd和xlwt进行excel读写&#xff1b;用openpyxl进行excel读写&#xff1b;用pandas进行excel读写&#xff1b; 一、数据准备 为了方便演示&#xff…

基于深度学习的动物识别系统(YOLOv5清新界面版,Python代码)

摘要&#xff1a;动物识别系统用于识别和统计常见动物数量&#xff0c;通过深度学习技术检测日常几种动物图像识别&#xff0c;支持图片、视频和摄像头画面等形式。在介绍算法原理的同时&#xff0c;给出Python的实现代码、训练数据集以及PyQt的UI界面。动物识别系统主要用于常…

C++ , STL常用容器

STLSTL初识STL的诞生STL基本概念STL六大组件STL中的容器、算法、迭代器容器算法迭代器初识STL — 常用容器string容器vector容器deque容器stack容器queue容器list容器set/ multiset 容器map/ multimap 容器C 模板. STL初识 STL的诞生 长久以来&#xff0c;软件界一直希望建立…

最好用的Markdown编辑器:MWeb Pro mac

MWeb pro Mac中文版是一款非常好用的Markdown编辑器和博客生成工具&#xff0c;支持语法高亮&#xff0c;预览&#xff0c;Fenced code blocks和代码高亮&#xff0c;Math ML支持&#xff0c;具有导出HTML/PDF&#xff0c;自定编辑器主题&#xff0c;字数统计&#xff0c;大纲视…

DRAM功能介绍与基础概念

目录 ROM与RAM DRAM定义与形态 DRAM存储单元 DRAM架构和工作流程 存储器是计算机系统中的记忆设备&#xff0c;用来存储程序和各种数据信息&#xff0c;存储器的存储介质主要采用半导体器件和磁性材料。接下来简单介绍存储器的主要分类。 按存储介质可以分类为半导体存储器…

2023年Android现代开发

2023年现代Android开发 下面与大家分享如何构建具有2023年最新趋势的Android应用程序。 Android是什么&#xff1f; Android 是一种基于 Linux 内核并由 Google 开发的开源操作系统。它用于各种设备&#xff0c;包括智能手机、平板电脑、电视和智能手表。 目前&#xff0c…