【寸铁的刷题笔记】树、dfs、bfs、回溯、递归(二)

news2024/11/17 17:42:55

【寸铁的刷题笔记】树、dfs、bfs、回溯、递归(二)

大家好 我是寸铁👊
金三银四,树、dfs、bfs、回溯、递归是必考的知识点✨
快跟着寸铁刷起来!面试顺利上岸👋
喜欢的小伙伴可以点点关注 💝


上期回顾

感谢大家的支持🌹🌹🌹
上期刷题笔记成功入选专栏第8名🔆

【寸铁的刷题笔记】树、dfs、bfs、回溯、递归(一)🎯

在这里插入图片描述

在这里插入图片描述

话不多说,开始新的篇章,继续刷起来💪


124. 二叉树中的最大路径和

思路

要求:返回其最大路径和
做法:路径和:枚举每个点作为起点,加上左右子树的值,取最大值即可。
先递归处理根节点的左右分支,向下走到底,把叶子节点的最大路径和取一个最大值。
回溯:向上回溯时,会计算上层根节点的路径和,继续取一个最大值。
返回:由于每个节点只能选一条路走,最大路径和下应该选择左右分支的最大值分支

代码

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    int maxSum = Integer.MIN_VALUE;
    public int maxPathSum(TreeNode root) {
        //递归函数入口
        maxGain(root);
        //返回最大路径和
        return maxSum;
    }
    //题意分析:
    /*
    要求:返回其最大路径和
    做法:路径和:枚举每个点作为起点,加上左右子树的值,取最大值即可。
    先递归处理根节点的左右分支,向下走到底,把叶子节点的最大路径和取一个最大值。
    回溯:向上回溯时,会计算上层根节点的路径和,继续取一个最大值。
    返回:由于每个节点只能选一条路走,最大路径和下应该选择左右分支的最大值分支
    */
    public int maxGain(TreeNode node){
        if(node == null){
            return 0;
        }
        //向左递归,计算左子树的叶子节点的最大路径和
        //如果小于0 则不选该分支 因为选了后路径和反而更小
        int leftGain = Math.max(maxGain(node.left) , 0);
        //向右递归,计算右子树的叶子节点的最大路径和
       //如果小于0 则不选该分支 因为选了后路径和反而更小
        int rightGain = Math.max(maxGain(node.right) , 0);
        //计算
        //回溯时,会依次把上层非叶子节点做为根节点,计算其路径和
        int priceNewPath = node.val + leftGain + rightGain;
        //把每次计算的结果取一个max
        maxSum = Math.max(maxSum , priceNewPath);
        //返回一条较大路径 给上层节点继续计算路径和
        return node.val + Math.max(leftGain , rightGain);
    }
}

236. 二叉树的最近公共祖先

思路

核心思想:
不断向上层返回递归左、右子树的结果
再根据结果是否存在p、q 确定返回的最近公共祖先

模拟分析图

在这里插入图片描述
在这里插入图片描述

代码

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    //核心思想:
    //不断向上层返回递归左、右子树的结果
    //再根据结果是否存在p、q 确定返回的最近公共祖先
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        //如果说根节点为空 则向上返回null即可
        if(root == null)return null;
        //这里是针对两种情况
        //一种是递归遍历时,遍历到的节点为p或者q则向上返回root
        //一种是p为当前的根节点,q为p所在树的后面节点出现,则直接向上返回root即可
        if(root == p || root == q)return root;
        //左、右、中
        //后序遍历 根据递归搜索到的左、右子树节点的情况进行判断
        //递归左子树
        TreeNode left = lowestCommonAncestor(root.left , p , q);
        //递归右子树 
        TreeNode right = lowestCommonAncestor(root.right , p , q);

        //中的逻辑
        //如果说左子树和右子树不为空
        //则当前的root就是最近公共祖先
        //向上返回即可
        if(left != null && right != null){
            return root;
        }else if(left != null && right == null){
            //说明 左子树为最近公共祖先 向上返回
            return left;
        }else if(left == null && right != null){
            //说明 右子树为最近公共祖先 向上返回
            return right;
        }else{
            return null;
        }
    }
}


102. 二叉树的层序遍历

考点

层序遍历、BFS

思路

思路:借助队列实现层序遍历,维护一个节点队列,记录队列的长度。
每次只弹出这一层的节点,把弹出节点添加到结果队列中。
再把弹出节点的左孩子、右孩子添加到节点队列中。
用于下一次节点队列节点的遍历与弹出。

代码


class Solution {
    /*
    思路:借助队列实现层序遍历,维护一个节点队列,记录队列的长度。
    每次只弹出这一层的节点,把弹出节点添加到结果队列中。
    再把弹出节点的左孩子、右孩子添加到节点队列中。
    用于下一次节点队列节点的遍历与弹出。
    */
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> res = new ArrayList<>();
        if(root != null){
            Queue<TreeNode>queue = new LinkedList<>();
            queue.offer(root);
            int size;
            TreeNode node;
            while(!queue.isEmpty()){
                List<Integer>ans = new ArrayList<>();
                size = queue.size();
                while(size-- > 0){
                    node = queue.poll();
                    ans.add(node.val);
                    if(node.left != null)queue.offer(node.left);
                    if(node.right != null)queue.offer(node.right);
                }
                res.add(ans);
            }
        }
        return res;
    }
}

199. 二叉树的右视图

考点

层序遍历、BFS

思路

遍历每一层节点时,把他加入节点队列。获取当前队列的长度,弹出节点时,将其左右子孩子都加入队列中,用于下一轮队列的弹出,弹出最后一个节点时,直接将该节点的值添加到结果队列。

代码


class Solution {
    public List<Integer> rightSideView(TreeNode root) {
        //创建一个队列用于存储二叉树右视图节点的值
        List<Integer> res = new ArrayList<>();
        if(root != null){
            //创建队列,用于层序遍历(bfs),存入每一行的点
            Queue<TreeNode>queue = new LinkedList<>();
            //先把根节点添加到队列中
            queue.offer(root);
            //队列的大小,放到外面,减少内存开销。
            int size;
            //存储从队列弹出来的节点,用于把弹出节点的值写入res队列中。
            TreeNode node;
            while(!queue.isEmpty()){
                size = queue.size();
                while(size -- > 0){
                    node = queue.poll();
                //不知道右视图看到的节点情况
                //索性每次弹出节点时,把节点的左孩子和右孩子都添加到队列中。
                    if(node.left != null)queue.offer(node.left);
                    if(node.right != null)queue.offer(node.right);

                //由于是从左到右遍历,入队,最后一个节点为最右侧节点
                //弹出最后一个节点时,把节点的值添加到res中。
                //注意这里是size-- 当size为1时,即为最后一个节点,--后为0。
                    if(size == 0)res.add(node.val);
                }
            }
        }
        return res;
    }
}

637. 二叉树的层平均值

考点

层序遍历、BFS

思路

思路:遍历每一层的节点,将其子孩子添加到队列,获取队列长度。
用临时变量计算每一层的节点的和值,再除以队列长度,最后添加到结果队列中即可。

代码


class Solution {
    /*
    思路:遍历每一层的节点,将其子孩子添加到队列,获取队列长度。
    用临时变量计算每一层的节点的和值,再除以队列长度,最后添加到结果队列中即可。
    */
    public List<Double> averageOfLevels(TreeNode root) {
        List<Double>res = new ArrayList<>();
        if(root != null){
            Queue<TreeNode>queue = new LinkedList<>();
            queue.offer(root);
            int size;
            TreeNode node;
            while(!queue.isEmpty()){
                double sum = 0;
                size = queue.size();
              for(int i = 0; i < size; i++){
                   node = queue.poll();
                   sum += node.val; 
                   if(node.left != null)queue.offer(node.left);
                   if(node.right != null)queue.offer(node.right);
                }
                res.add(sum / size);
            }                
            }
        return res;
    }
}

103. 二叉树的锯齿形层序遍历

考点

层序遍历、双端队列、BFS

思路

根据结果队列的层数,如果说层数是偶数(层数从0开始),则进行从左到右遍历,即头插。如果说层数是奇数(层数从0开始),则进行从右到左遍历,即尾插

代码

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
        Queue<TreeNode>queue = new LinkedList<>(); //维护一个队列,存储节点
        List<List<Integer>>res = new ArrayList<>();//存储最后的结果
        if(root != null){
            queue.offer(root);
            int size;
            TreeNode node;
            while(!queue.isEmpty()){//只有队列不为空的时候,再进行弹出队列的节点操作。
                size = queue.size();//更新当前的队列size,确定弹出当前多少个节点用于下一轮的更新。
                List<Integer>ans = new LinkedList<>();//存储这一层的节点
                while(size -- > 0){
                    node = queue.poll();//弹出节点
                    //如果说层数(从0开始)为偶数,则进行尾插,即从左到右
                    if(res.size() % 2 == 0)ans.addLast(node.val);
                    //否则,进行头插,则是从右到左
                    else ans.addFirst(node.val);
                    //把弹出节点的左、右孩子入队
                    if(node.left != null)queue.offer(node.left);
                    if(node.right != null)queue.offer(node.right);
            }
            res.add(ans);//添加ans到最后的结果队列res中
            }
        }
        return res;
    }
}

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

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

相关文章

【MySQL 探索之旅】初始MySQL数据库

&#x1f4da;博客主页&#xff1a;爱敲代码的小杨. ✨专栏&#xff1a;《Java SE语法》 | 《数据结构与算法》 | 《C生万物》 ❤️感谢大家点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;&#xff0c;您的三连就是我持续更新的动力❤️ &#x1f64f;小杨水平有…

【多线程】synchronized 关键字 - 监视器锁 monitor lock

synchronized 1 synchronized 的特性1) 互斥2) 可重入 2 synchronized 使用示例1) 修饰代码块: 明确指定锁哪个对象.2) 直接修饰普通方法: 锁的 SynchronizedDemo 对象3) 修饰静态方法: 锁的 SynchronizedDemo 类的对象 3 Java 标准库中的线程安全类 1 synchronized 的特性 1)…

代码随想录算法训练营第四十天|343. 整数拆分 96.不同的二叉搜索树

343. 整数拆分 链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 思路: 动态规划的题目虽然说是要先确定dp数组的含义&#xff0c;再确定递归公式&#xff0c;但是总感觉这两者是相辅相成的&#xff0c;是一起出来的&#xff0c;但是到此&#xff0c;dp数组…

第十二天-ppt的操作

目录 创建ppt文档 安装 使用 段落的使用 段落添加数据 段落中定义多个段落 自定义段落 ppt插入表表格 PPT插入图片 读取ppt 读取ppt整体对象 ​编辑 获取ppt文本 获取表格内容 创建ppt文档 安装 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple python…

ARM处理器有哪些工作模式和寄存器?各寄存器作用是什么?ARM异常中断处理流程?

《嵌入式工程师自我修养/C语言》系列——ARM处理器有哪些工作模式和寄存器&#xff1f;各寄存器作用是什么&#xff1f; 一、ARM处理器的工作模式及寄存器1.1 ARM处理器的工作模式1.2 ARM处理器中的寄存器 二、ARM 异常中断处理2.1 什么是异常&#xff1f;异常向量表是什么&…

自动化操作读写Excel —— xlrd 和 xlwt 模块参数说明与代码实战【第95篇—自动化操作读写Excel 】

自动化操作读写Excel —— xlrd 和 xlwt 模块参数说明与代码实战 在日常工作中&#xff0c;Excel表格是不可或缺的数据处理工具。为了提高工作效率&#xff0c;Python中的xlrd和xlwt模块为我们提供了强大的功能&#xff0c;使得自动化操作Excel变得更加简便。本文将介绍xlrd和…

SpringBoot -【BeanFactory】基础使用及应用场景

1.介绍 在 Spring 框架中&#xff0c;BeanFactory 是 Spring IoC 容器的核心接口&#xff0c;负责管理 bean 的创建、配置和装配。它是 Spring IoC 容器的基础。BeanFactory 接口定义了一系列方法&#xff0c;用于管理和访问容器中的 bean 对象。 BeanFactoryAware 用于在 Sp…

iOS调用系统已安装地图及内置地图实现

info.plist要添加scheme: 1.地图列表: NSArray *mapKeys=[[NSArray alloc] initWithObjects:@"com.autonavi.minimap",@"com.baidu.BaiduMap",@"com.google.android.apps.maps",@"com.tencent.map", nil]; NSArray *mapSchemes=[[NS…

劫持已经存在的DLL

这里找到一个成功加载的 这里先把原来程序正常的dll改名为libEGL1.dll&#xff0c;然后将我们自己的dll改名为libEGL.dll 然后再重新执行程序&#xff0c;这里同样是弹出了窗口

《教育教学论坛》期刊是什么级别?是核心期刊吗?是C刊吗?

​标题解答 问&#xff1a;《教育教学论坛》版面费&#xff1f; 答&#xff1a;VX:JDQJDQ444 问&#xff1a;《教育教学论坛》是核心期刊吗&#xff1f; 答&#xff1a;不是核心期刊 问&#xff1a;《教育教学论坛》是正规期刊吗&#xff1f; 答&#xff1a;是正规期刊 …

vue中使用echarts绘制双Y轴图表时,刻度没有对齐的两种解决方法

文章目录 1、原因2、思路3、解决方法3.1、使用alignTicks解决3.2、结合min和max属性去配置interval属性1、首先固定两边的分隔的段数。2、结合min和max属性去配置interval。 1、原因 刻度在显示时&#xff0c;分割段数不一样&#xff0c;导致左右的刻度线不一致&#xff0c;不…

【Java程序设计】【C00283】基于Springboot的校园志愿者管理系统(有论文)

基于Springboot的校园志愿者管理系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的校园志愿者管理系统 本系统分为系统功能模块、管理员功能模块以及志愿者功能模块。 系统功能模块&#xff1a;用户进入到系统…

Java的编程之旅27——继承

1.继承的简介 继承是面向对象编程中的一个重要概念&#xff0c;指的是一个类可以继承另一个类的属性和方法。被继承的类称为父类或基类&#xff0c;继承这个父类的类称为子类或派生类。 通过继承&#xff0c;子类可以继承父类的属性和方法&#xff0c;使得子类具有相似的行为…

CSS实现半边边框(只有边框的部分可见)

CSS实现半边边框&#xff08;只有边框的部分可见&#xff09; <div class"part box"><h1>内容</h1><!-- 绘出下面两个对角边框--><div class"part-footer"></div> </div>主要代码 .box {width: 100px;height:…

博睿数据率先发布HarmonyOS NEXT系统的应用异常观测SDK

近日&#xff0c;博睿数据作为业界领先的厂商&#xff0c;凭借对技术的深刻理解和前瞻性视野&#xff0c;率先发布支持HarmonyOS NEXT&#xff08;"纯血鸿蒙"&#xff09;系统的应用异常观测SDK&#xff0c;实现了应用异常的全面回溯。这一突破性技术将引领行业标准&…

为什么前端开发变得越来越复杂了?这可能是我们的错

前端训练营&#xff1a;1v1私教&#xff0c;终身辅导计划&#xff0c;帮你拿到满意的 offer。 已帮助数百位同学拿到了中大厂 offer。欢迎来撩~~~~~~~~ Hello&#xff0c;大家好&#xff0c;我是 Sunday。 最近有很多同学来问我&#xff1a;“Sunday 老师&#xff0c;前端学起…

从 0 开始在项目中引入 Element Plus

此前&#xff0c;已经写文章介绍了如何《从 0 开始创建 Vue 项目》&#xff0c;今天我们来说说&#xff0c;怎么在 Vue 项目中引入 Element Plus。 文章目录 一、简介二、准备三、安装 Element Plus四、快速上手五、自动导入总结 一、简介 Element Plus 是一个基于 Vue 3.0 重…

【实战篇】Redis单线程架构的优势与不足

前言 01 Redis中的多线程02 I/O多线程03 Redis中的多进程问题 04 结论 很多人都遇到过这么一道面试题&#xff1a;Redis是单线程还是多线程&#xff1f;这个问题既简单又复杂。说他简单是因为大多数人都知道Redis是单线程&#xff0c;说复杂是因为这个答案其实并不准确。 难道R…

uniapp腾讯地图JavaScript Api,H5端和原生APP端可用

因项目需要&#xff0c;在uniapp中集成使用腾讯地图&#xff0c;为了方便维护&#xff0c;希望通过一套代码实现H5和APP同时可用。H5显示相对简单&#xff0c;APP端比较麻烦&#xff0c;记录下实现过程 一、集成步骤 1.使用 renderjs script标签使用renderjs&#xff0c;因为…

互联网加竞赛 机器视觉 opencv 深度学习 驾驶人脸疲劳检测系统 -python

文章目录 0 前言1 课题背景2 Dlib人脸识别2.1 简介2.2 Dlib优点2.3 相关代码2.4 人脸数据库2.5 人脸录入加识别效果 3 疲劳检测算法3.1 眼睛检测算法3.2 打哈欠检测算法3.3 点头检测算法 4 PyQt54.1 简介4.2相关界面代码 5 最后 0 前言 &#x1f525; 优质竞赛项目系列&#x…