Java 【数据结构OJ题十道】—— 二叉树篇2

news2024/9/25 23:12:36

文章目录

  • 一、二叉树前序遍历
  • 二、二叉树层序遍历
  • 三、按照之字形打印二叉树
  • 四、二叉树中和为某一值的路径(一)
  • 五、二叉搜索树与双向链表
  • 六、合并二叉树
  • 七、二叉树的镜像
  • 八、判断是否为二叉搜索树
  • 九、判断是否为完全二叉树
  • 十、判断是否为平衡二叉树
  • 总结


提示:本人是正在努力进步的小菜鸟,不喜勿喷~,如有大佬发现某题有更妙的解法和思路欢迎提出讨论~

一、二叉树前序遍历

OJ链接

📌📌📌题目描述:
给你二叉树的根节点 root ,返回它节点值的 ==前序== 遍历(返回一个==数组==)
返回值: int[]

📌📌📌解题思路:
根据 “根左右” 的原则逐个遍历二叉树,并用 ArrayList 记录二叉树的每一个结点,递归结束后把 ArrayList 中记录的结点逐个放在数组中

⚠️⚠️⚠️注意:
1,如果二叉树为空,返回的数组为:“ [ ] ”,所以数组长度必须初始化为0
2,不能 在递归过程中每遇到一个非空结点就放入数组中,因为无法确定二叉树的结点个数,从而 不能 确定数组长度,并且数组 不能 动态的每添加一个元素就增大一个容量,但是数据结构中存在类似功能的集合类:ArrayList
3,把先序遍历数组这个方法独立出来,每遍历一个非空结点就在 ArrayList 中插入一个数据,递归结束后 ArrayList 得到的就是二叉树的先序遍历序列
4,最后创建和 ArrayList 长度相同的数组,遍历数组设置每个下标的值即可

代码实现:

public class PreorderTraversal {
    public int[] preorderTraversal (TreeNode root) {
        int[] array = new int[0];
        ArrayList<Integer> arrayList = new ArrayList<>();
        preorder(arrayList,root);
        int len = arrayList.size();
        if(len == 0) {
            return array;
        }
        array = new int[len];
        for(int i = 0; i < len; i++) {
            array[i] = arrayList.get(i);
        }
        return array;
     
    }
    // 先序遍历并在 ArrayList 中添加数据
    // public void preorder(ArrayList arrayList, TreeNode root) {
    // 会发生警告:“ 参数化类“ArrayList”的原始使用 ” ——使用泛型类做参数要加上 “ <对应类型> ”
    public void preorder(ArrayList<Integer> arrayList, TreeNode root) {
        if(root == null) {
            return;
        }
        arrayList.add(root.val);
        preorder(arrayList,root.left);
        preorder(arrayList,root.right);
    }
}

二叉树的中序,后序遍历的思路和先序遍历一致,只需要改变递归过程中 以下三行代码的先后执行顺序即可

arrayList.add(root.val);
preorder(arrayList,root.left);
preorder(arrayList,root.right);


二、二叉树层序遍历

OJ链接

📌📌📌题目描述:
给定一个二叉树,返回该二叉树层序遍历的结果,(从左到右,一层一层地遍历)返回的是一个 ArrayList 集合类
返回值: ArrayList<ArrayList<Integer>>

📌📌📌解题思路:
返回值是 ArrayList 集合类,并且要一层一层的记录,所以 ArrayList 的每一个元素也是一个 ArrayList ,如图:在这里插入图片描述
有点类似于二维数组。重点在于如何在层序遍历的同时分层,可以分成两部分:层序遍历 + 分层。
层序遍历与之前先序遍历不同,层序遍历不使用递归,而是利用队列这种数据结构。如果能在访问(出队)根节点的同时,入队 这个根左右子树的根节点,然后再做到这一层的根节点全部出队后,再依次出队下一层
在这里插入图片描述
如何把这个队列分层呢?
在这里插入图片描述
每一层的节点个数,就是队列出队的次数,所以定义一个 size,控制出队的循环次数即可

⚠️⚠️⚠️注意:
1,循环之前让根节点 root 入队,循环的大前提条件是队列不为空,如果队列为空说明所有的结点全部出队,退出循环返回 list
2,内部循环控制每一层的循环次数,也就是这一层的节点个数, 每层循环开始前 new 一个新的 ArrayList
3,Queue 的泛型类型必须是 TreeNode 而不能是 Integer ,如果是 Integer ,在每层的 ArrayList 中插入时看似可以直接、方便的插入 queue
4. ❓❓❓queue.poll()方法的返回值也是 TreeNode 类型,需用一个变量 node 接收才能访问到这个结点的 val 域,同时在判断左右孩子是否为空时,是 if (node.left != null),而不是 if (root.left != null),如果是后者,代码执行到此说明 root 不为空,而 if 语句每次都会进来,最后会访问空结点的左右孩子,发生空指针异常

代码实现:

public ArrayList<ArrayList<Integer>> levelOrder (TreeNode root) {
        ArrayList<ArrayList<Integer>> list = new ArrayList<>();
        if (root == null) {
            return list;
        }
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()) {
            int size = queue.size();
            ArrayList<Integer> inList = new ArrayList<>();
            while (size > 0) {
                TreeNode node = queue.poll();
                inList.add(node.val);
                if (node.left != null) {
                    queue.offer(node.left);
                }
                if (node.right != null) {
                    queue.offer(node.right);
                }
                size--;
            }
            list.add(inList);
        }
        return list;
    }

三、按照之字形打印二叉树

OJ链接

📌📌📌题目描述:
在这里插入图片描述
返回值: ArrayList<ArrayList<Integer>>

📌📌📌解题思路:
通过题目描述得知,之字形打印就是在上一题层序遍历的输出结果上, 奇数行从左往右访问, 偶数行从右往左遍历,最简单的方式就是在上一题的代码上, 再写一个“反转”函数

代码实现:

public class PrintZ {
    public ArrayList<ArrayList<Integer>> Print(TreeNode pRoot) {
        ArrayList<ArrayList<Integer>> list = new ArrayList<>();
        if (pRoot == null) {
            return list;
        }
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(pRoot);
        int line = 0;
        while (!queue.isEmpty()) {
            int size = queue.size();
            ArrayList<Integer> inList = new ArrayList<>();
            while (size > 0) {
                TreeNode node = queue.poll();
                inList.add(node.val);
                if (node.left != null) {
                    queue.offer(node.left);
                }
                // 如果偶数行就反转,把顺序改成逆序
                if (node.right != null) {
                    queue.offer(node.right);
                }
                size--;
            }
            if((++line)%2 == 0) {
                list.add(reverse(inList));
            }else {
                list.add(inList);
            }
        }
        return list;
    }
    // 反转ArrayList
    private ArrayList<Integer> reverse(ArrayList<Integer> arrayList) {
        int size = arrayList.size();
        ArrayList<Integer> ret = new ArrayList<>();
        for (int i = 0; i < size; i++) {
            ret.add(arrayList.get(size-i -1 ));
        }
        return ret;
    }
}

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

OJ链接

📌📌📌题目描述:
在这里插入图片描述
返回值: boolean

📌📌📌解题思路:
判断是否有一条路径(走到头时), 一路上的结点 val 值综合相当于 sum

利用遍历思想, 前序遍历, 递归时传递 sum, 每遇到一个结点就减去当前结点的 val 值, 如果当前结点的左右孩子节点都为 null 说明当前结点是某条路径的尽头

此时进行判断 sum 和 0 是否相同, 如果 sum 等于 0 , 说明这一路是对的, 返回true,否则返回false

但是!!
返回 fasle 之后 ,有可能去右子树继续判断呢, 所以如果这条路不满足, 要把当前结点的 val 值加回来, 再返回

⚠️⚠️⚠️注意:
一定是当前结点为叶子节点, 也就是某条路径的尽头时再判断 sum 和 0 的关系

代码实现:

public class HasPathSum{
    public boolean hasPathSum (TreeNode root, int sum) {
        if (root == null) {
            return false;
        }
        sum -= root.val;
        if (sum == 0 && (root.left == null && root.right == null)) {
            return true;
        }
        if (sum != 0 && (root.left == null && root.right == null)) {
            sum += root.val;
            return false;
        }
        boolean bLeft = hasPathSum(root.left, sum);
        boolean bRight = hasPathSum(root.right, sum);
        return bLeft || bRight;
    }
}

方法2: 也可以用加法, 多传递一个count, 从 0 往上加, 走到尽头时判断 count 是否和 sum 相同, 相同说明这条路径找到了, 返回true

代码实现:

public class HasPathSum2 {
    public boolean hasPathSum (TreeNode root, int sum) {
        int count = 0;
        return hasPathSumChild(root,sum,count);
    }
    public boolean hasPathSumChild(TreeNode root, int sum, int count) {
        if (root == null) {
            return false;
        }
        count += root.val;
        if (sum == count &&
                (root.left == null && root.right == null)) {
            return true;
        }
        if (sum != count &&
                (root.left == null && root.right == null)) {
            count -= root.val;
            return false;
        }
        boolean leftIsTrue = hasPathSumChild(root.left, sum,count);
        boolean rightIsTrue = hasPathSumChild(root.right, sum,count);
        return leftIsTrue || rightIsTrue;
    }
}

五、二叉搜索树与双向链表

OJ链接

📌📌📌题目描述:
在这里插入图片描述
返回值: TreeNode

📌📌📌解题思路:

首先分成两部分:树=》链表 + 寻找链表头结点

题目给定的是一个二叉搜索树, 二叉搜索树的性质是, 中序遍历时一定是有序的, 而题目要求正是把树转化成链表后的前驱后继符合二叉搜索树中序遍历的顺序

加之要在“原树”上操作, 所以本题基本思想就是对二叉搜索树进行中序遍历

问题在于, 如何更改每个结点的左右引用

既然是以左中右的顺序访问二叉搜索树, 当然是左遍历完,回到当前根节点的时候进行操作——更改引用, 我们需要定义一个 prevRoot 记录下来前一个结点, 让当前根节点 root 的 left 引用上一个结点,然后当 prevRoot 不为空时,让它的 right 引用当前根节点

⚠️⚠️⚠️注意:
prevRoot.right = root, 执行这条语句之前一定要对 prevRoot 判空, 避免空指针异常

代码实现:

public class TreeAndLinkedList {
    // 把二叉搜索树更改为有序双向链表并返回链表头结点
    public TreeNode prevRoot;
    public TreeNode Convert(TreeNode pRootOfTree) {
        if(pRootOfTree == null) {
            return null;
        }
        // 通过中序遍历,从树转化成双向链表
        inOrder(pRootOfTree);
        return findHead(prevRoot);
    }
    
    private void inOrder(TreeNode root) {
        if(root == null) {
            return ;
        }
        inOrder(root.left);
        // 修改left指向
        root.left = prevRoot;
        // 修改right指向
        if(prevRoot != null) {
            prevRoot.right = root;
        }
        prevRoot = root;
        inOrder(root.right);
    }
    private TreeNode findHead(TreeNode root) {
        while(root.left != null) {
            root = root.left;
        }
        return root;
    }
}

六、合并二叉树

OJ链接

📌📌📌题目描述:
已知两颗二叉树,将它们合并成一颗二叉树。合并规则是:都存在的结点,就将结点值加起来,否则空的位置就由另一个树的结点来代替。例如:
两颗二叉树是:
在这里插入图片描述
在这里插入图片描述
返回值 : TreeNode

📌📌📌解题思路:
典型的子问题思路, 对两棵树的相同位置上每一个结点判断即可

⚠️⚠️⚠️注意:
需要注意的是, 每次对两个结点判断操做后, 返回的是合并之后树的根节点, 可以让 t2 往 t1 上合并,最后返回 t1 的根结点, 也可以让 t1 往 t2 上合并, 最后返回 t2 的根节点

如果 t2 往 t1 上合并, 那么在左右递归时, 就需要接收返回值, 使当前根节点引用左右子树

代码实现:

public class MergeTree {
    public TreeNode mergeTrees (TreeNode t1, TreeNode t2) {
        if(t1 == null && t2 == null){
            return null;
        }
        if(t1 == null && t2 != null) {
            return t2;
        }
        if(t1 != null && t2 != null ){
            t1.val += t2.val;
        }
        if(t1 == null || t2 == null) {
            return t1;
        }
        t1.left = mergeTrees(t1.left, t2.left);
        t1.right = mergeTrees(t1.right,t2.right);
        return t1;
    }
}

七、二叉树的镜像

OJ链接

📌📌📌题目描述:
在这里插入图片描述
返回值: TreeNode

📌📌📌解题思路:
典型的子问题思路, 交换每一棵(子)树的左右子树即可

代码实现:

public class Mirror {
    public TreeNode Mirror (TreeNode pRoot) {
        if(pRoot == null) {
            return null;
        }
        TreeNode tmp = pRoot.right;
        pRoot.right = pRoot.left;
        pRoot.left = tmp;
        Mirror(pRoot.left);
        Mirror(pRoot.right);
        return pRoot;
    }
}

八、判断是否为二叉搜索树

OJ链接

📌📌📌题目描述:
在这里插入图片描述
返回值 : boolean

📌📌📌解题思路:
利用搜索二叉树的特质, 对这棵树进行中序遍历, 存储中序遍历序列, 判断该序列是否有序, 如果满足有序说明是搜索二叉树, 否则不是

代码实现:

public class IsValidBST {
    public boolean isValidBST (TreeNode root) {
        ArrayList<Integer> list = new ArrayList<>();
        inorder(list, root);
        return jude(list);

    }
    private void inorder(ArrayList<Integer> list, TreeNode root) {
        if(root == null) {
            return;
        }
        inorder(list, root.left);
        list.add(root.val);
        inorder(list, root.right);
    }
    private boolean jude(ArrayList<Integer> list) {
        for(int i = 0; i < list.size() -1; i++) {
            if(list.get(i)> list.get(i+1)) {
                return false;
            }
        }
        return true;
    }
}

九、判断是否为完全二叉树

OJ链接

📌📌📌题目描述:
在这里插入图片描述
返回值: boolean

📌📌📌解题思路:
利用完全二叉树的性质, 如果中间下标位置的结点有空缺, 说明不是完全二叉树

所以对这棵树进行层序遍历, 利用队列这种数据结构, 根节点入队, 当队列不为空时进入循环, 出队一次, 并让它的左右孩子结点入队(队列可以offer(null), 优先级队列不可以), 出队时遇见 null, 退出循环

退出循环后检查队列中剩余数据是否还有非空数据, 如果存在非空数据说明不是完全二叉树

⚠️⚠️⚠️注意:
队列可以 offer(null), 优先级队列不可以

代码实现:

public class IsCompleteTree {
    public boolean isCompleteTree (TreeNode root) {
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        boolean mark = true;
        while (!queue.isEmpty()) {
            TreeNode node = queue.poll();
            if (node == null) {
                mark = false;
            } else {
                if (mark == false) {
                    return false;
                }
                queue.offer(node.left);
                queue.offer(node.right);
            }
        }
        return true;
    }
}

十、判断是否为平衡二叉树

OJ链接
📌📌📌题目描述:
在这里插入图片描述
返回值: boolean

📌📌📌解题思路:
判断是否为平衡二叉树的规则就是左右子树高度差是否超过1, 典型的子问题思路

判断树的高度代码上稍加修改即可

利用递归, 自下而上判断当前根结点所在的子树是否平衡: 获取了左右子树的高度之后, 相减取绝对值, 大于1说明不平衡, (所以要递归接收左右子树的高度)

⚠️⚠️⚠️注意:
如果发现子树不平衡, 那么整棵树一定不平衡, 所以当子树不平衡时就可以返回 -1, 减少对另一颗子树的无效递归, 一路返回-1, 最终在根节点判断时, 任何数和-1相减后去绝对值都大于1, 结论同样是不平衡

代码实现:

public class IsBalanced {
    public boolean IsBalanced_Solution(TreeNode root) {
        return treeHigh(root) >=0;

    }
    public int treeHigh(TreeNode root) {
        if (root == null) {
            return 0;
        }
        if (root.left == null && root.right == null ) {
            return 1;
        }
        int leftHigh = treeHigh(root.left);
        if (leftHigh == -1) {
            return -1;
        }
        int rightHigh = treeHigh(root.right);
        if (rightHigh == -1) {
            return -1;
        }
        
        if (Math.abs(leftHigh - rightHigh) <= 1) {
            return Math.max(leftHigh, rightHigh) + 1;
        } else {
            return -1;
        }
    }
}

总结

以上是收录的十道关于二叉树的OJ题练习, 用作学习之余的整理分享, 仅供参考
如果本篇对你有帮助,请点赞收藏支持一下,小手一抖就是对作者莫大的鼓励啦😋😋😋~


上山总比下山辛苦
下篇文章见

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

TCP中RTT时延的理解

最近服务器环境部署了tcprtt网络时延监控&#xff0c;发现不同服务器不同节点之间的RTT时延表象非常奇怪&#xff0c;无法准确的判断服务器的网络情况。因此需要弄清楚什么是RTT&#xff0c;以及能否作为服务器网络性能的检测指标。 1、RTT是什么&#xff1f; TCP中的RTT指的是…

倾向得分匹配案例分析

一、倾向得分匹配法说明 倾向得分匹配模型是由Rosenbaum和Rubin在1983年提出的&#xff0c;首次运用在生物医药领域&#xff0c;后来被广泛运用在药物治疗、计量研究、政策实施评价等领域。倾向得分匹配模型主要用来解决非处理因素&#xff08;干扰因素&#xff09;的偏差。 …

为什么硬件性能监控很重要

当今的混合网络环境平衡了分布式网络和现代技术的实施。但它们并不缺少一个核心组件&#xff1a;服务器。保持网络正常运行时间归结为监控和管理导致网络停机的因素。极有可能导致性能异常的此类因素之一是硬件。使用硬件监控器监控网络硬件已成为一项关键需求。 硬件监视器是…

连接金蝶云星空,数据交互轻松搞定!丨三叠云

金蝶云星空 路径 拓展 >> 插件 功能简介 新增插件「金蝶云星空」。 用户可通过配置「金蝶云星空」插件&#xff0c;就可以实时获取「金蝶云星空」的数据&#xff0c;同时支持回填数据至金蝶系统内。 地图视图 路径 表单 >> 表单设计 功能简介 新增「地图视…

prometheus+cadvisor监控docker

官方解释 cAdvisor&#xff08;ContainerAdvisor&#xff09;为容器用户提供了对其运行容器的资源使用和性能特性的了解。它是一个正在运行的守护程序&#xff0c;用于收集、聚合、处理和导出有关正在运行的容器的信息。具体来说&#xff0c;它为每个容器保存资源隔离参数、历史…

活动目录(Active Directory)组策略管理工具

活动目录&#xff08;Active Directory&#xff09;是面向Windows Standard Server、Windows Enterprise Server以及 Windows Datacenter Server的目录服务。&#xff08;Active Directory不能运行在Windows Web Server上&#xff0c;但是可以通过它对运行Windows Web Server的…

虚拟数字人直播带货相比人工有哪些优势?

新经济时代的到来&#xff0c;彻底改变了传统的消费方式。虚拟数字人的出现&#xff0c;标志着新一波的消费升级到来。虚拟数字人直播带货&#xff0c;不仅降低了商家的带货成本&#xff0c;拉近了商家与消费者的距离&#xff0c;也给消费者带来全新的消费方式。 花西子虚拟形象…

华为OD机试模拟题 用 C++ 实现 - 删除最少字符(2023.Q1)

最近更新的博客 【华为OD机试模拟题】用 C++ 实现 - 最多获得的短信条数(2023.Q1)) 文章目录 最近更新的博客使用说明删除最少字符题目输入输出描述示例一输入输出示例二输入输出Code使用说明 参加华为od机试,一定要注意不要完全背诵代码,需要理解之后模仿写出,通过率…

在Redis集群模式下使用pipeline进行批量操作

最近开始又接触到了Redis&#xff0c;之前在工作中使用Redis的时候&#xff0c;由于QPS不高&#xff0c;都是直接get/set搞定了。这次遇到的业务数据量比较大&#xff0c;更新也很频繁&#xff0c;Redis使用是集群模式&#xff0c;所以本文记录下捣鼓出来的如何在集群模式下使用…

动手学深度学习(第二版)学习笔记 第三章

第三章 线性神经网络 代码&#xff1a;d2l-zh/pytorch/chapter_linear-networks 3.1 线性回归 3.1. 线性回归 — 动手学深度学习 2.0.0 documentation 解析解 线性回归的解可以用一个公式简单地表达出来&#xff0c;这类解叫作解析解&#xff08;analytical solution&…

深度学习实战19(进阶版)-SpeakGPT的本地实现部署测试,基于ChatGPT在自己的平台实现SpeakGPT功能

大家好&#xff0c;我是微学AI&#xff0c;今天给大家带来SpeakGPT的本地实现&#xff0c;在自己的网页部署&#xff0c;可随时随地通过语音进行问答&#xff0c;本项目项目是基于ChatGPT的语音版&#xff0c;我称之为SpeakGPT。 ChatGPT最近大火&#xff0c;其实在去年12月份…

「架构」全链路异步模式

总结自尼恩的全链路异步&#xff1a;网关纯异步化网关层的特点&#xff1a;不需要访问业务数据库只做协议转换和流量转发特点是 IO 密集型&#xff0c;特别适合纯异步的架构&#xff0c;可以极大的节省资源。如何进行网关异步化&#xff1f;使用高性能的通信框架Netty&#xff…

CSS3新增的视口单位Vh、Vw单位

定义vw&#xff1a;浏览器可见视口【宽度】的百分比&#xff08;1vw代表视窗【宽度】的1%&#xff09;vh&#xff1a;浏览器可见视口【高度】的百分比&#xff08;1vw代表视窗【高度】的1%&#xff09;vmin&#xff1a;当前 vw 和 vh 较小的一个值。vmax&#xff1a;当前 vw 和…

现在入行软测=49年入国军?三句话,让面试官再掏2K!

还有三五天就步入金三银四&#xff0c;很多软测人吐槽因为疫情&#xff0c;公司都在裁员&#xff0c;别说跳槽涨薪&#xff0c;能保住现在的工作就不错了。但也有那么一批人&#xff0c;凭借自己口才与实力拿到年薪近50W的offer。面试是初见1小时就要相互了解优缺点的过程&…

软考知识笔记 2023.2.24 2018下半年真题

答案&#xff1a; A BIOS (BasicInputOutputSystem) (基本输入输出系统) 是一组固化到计算机内主板上一个ROM芯片上的程序&#xff0c; 它保存着计算机最重要的基本输入输出的程序&#xff0c; 开机后自检程序和系统自启动程序&#xff0c; 它可从CMOS中读写系统设置的具体信息…

SpringBoot整合(六)多数据源和 JPA、MyBatis、JdbcTemplate 的集成

在springboot项目中&#xff0c;我们可能会碰到需要多数据源的场景。例如说&#xff1a; 读写分离&#xff1a;数据库主节点压力比较大&#xff0c;需要增加从节点提供读操作&#xff0c;以减少压力。多数据源&#xff1a;一个复杂的单体项目&#xff0c;因为没有拆分成不同的…

PPP简介,PPP分层体系架构,PPP链路建立过程及PPP的帧格式

PPP&#xff08;Point-to-Point Protocol&#xff09;是一种用于在两个网络节点之间传输数据的通信协议。它最初是为在拨号网络上进行拨号连接而开发的&#xff0c;现在已经被广泛应用于各种网络环境中&#xff0c;例如在宽带接入、虚拟专用网&#xff08;VPN&#xff09;等场景…

在linux中使用lftp和sftp下载文件(夹)

一、首先确保你的系统中已经下载了lftp和sftp。 1.安装lftp sudo apt install lftp sudo apt install screen 2.安装sftp 在Linux系统中&#xff0c;一般RedHat系统默认已经安装了openssh-client和openssh-server&#xff0c;即默认已经集成了sftp服务&#xff0c;不需要重…

LVGL8.3 集成 ST7789V 显示驱动和 CST816T 触摸屏驱动

LVGL8.3 集成 ST7789V 显示驱动和 CTS816S 触摸屏驱动起因效果&#xff08;正常显示&#xff0c;触摸屏可调换X&#xff0c;Y轴&#xff09;使用方式前提操作步骤最后参考起因 LVGL的ESP32 Drivers库中已经包含了大多数显示和触摸芯片的驱动&#xff0c;基本上只需要在MenuCon…

高级前端面试题汇总

iframe 有那些优点和缺点&#xff1f; iframe 元素会创建包含另外一个文档的内联框架&#xff08;即行内框架&#xff09;。 优点&#xff1a; 用来加载速度较慢的内容&#xff08;如广告&#xff09;可以使脚本可以并行下载可以实现跨子域通信 缺点&#xff1a; iframe 会…