java算法day13

news2024/9/21 4:23:15

java算法day13

  • 104 二叉树的最大深度
  • 111 二叉树的最小深度
  • 226 翻转二叉树
  • 101 对称二叉树
  • 100 相同的树

104 二叉树的最大深度

我最开始想到的是用层序遍历。处理每一层然后计数。思路非常的清楚。
迭代法:

/**
 * 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 int maxDepth(TreeNode root) {
        Deque<TreeNode> que = new ArrayDeque<>();
        int deepth = 0;
        //特判
        if(root==null){
            return deepth;
        }
        //还是根节点先入栈。思想就是层序遍历。每处理完一层,那么就计数+1。
        que.offerLast(root);
        while(!que.isEmpty()){
            int size = que.size();
            while(size>0){
                TreeNode temp = que.pollFirst();
                if(temp.left!=null){
                    que.offerLast(temp.left);
                }
                if(temp.right!=null){
                    que.offerLast(temp.right);
                }
                size--;
            }
            deepth++;
        }

        return deepth;
    }
}

递归解法在下面


111 二叉树的最小深度

我一开始想到的还是层序遍历。
唯一的变化就是判断什么时候停下来,就是处理节点的时候,如果某个节点没有叶子节点,那不就说明这层之后该节点就没有孩子嘞。就是最小深度。
迭代解法:

class Solution {
    public int minDepth(TreeNode root) {
        Deque<TreeNode> que = new ArrayDeque<>();
        if(root==null){
            return 0;
        }
        int count = 1;
        que.offerLast(root);
        while(!que.isEmpty()){
            int size = que.size();
            while(size>0){
                TreeNode temp = que.pollFirst();
                if(temp.left==null && temp.right==null){
                    return count;
                }
                if(temp.left!=null){
                    que.offerLast(temp.left);
                }
                if(temp.right!=null){
                    que.offerLast(temp.right);
                }
                size--;
            }
            count++;
            
        }
        return count;
    }
}

递归解法在下面


递归

接下来的题目几乎都用到了递归,这里就解决晕递归的问题。
写递归的时候要注意哪些?
1.不要一上来就扣细节,而是考虑这个过程中要做什么。
2.停止递归逻辑,处理逻辑,正常返回逻辑

这种在题解中称为子问题,和原问题模型。可以类比循环,在循环中我们总是要执行相同的逻辑,但是递归的特点在于,他需要在这个过程中,将计算的结果依次返给上一级。

想不到什么时候终止,就想想最底部的状态。
想不到处理逻辑怎么写,就想想如何进入下一层。

一句总结:想想怎么递下去,递到什么时候,什么时候归,归的过程中要干嘛。

二叉树的最大深度

思路:
正如递归的核心思想,不要上来就去扣递归的细节,而是想递归的过程中做了什么。

递归的过程我做了什么:最大的深度,就是左子树和右子树当中的最大深度,当返回上一层时,进行+1。

不从过程来考虑就是,return的结果就是左右子树的最大深度,然后到这一层嘞就是+1。感觉就是一眼看到了问题的本质。底部自己会去递归。

class Solution {
    public int maxDepth(TreeNode root) {
        if(root==null){
            return 0;
        }
        return Math.max(maxDepth(root.left),maxDepth(root.right))+1;
    }

    
}

二叉树的最小深度

一上来先粗略的考虑,这个思路是正确的,粗略的考虑就是递归计算左右子树的最小深度,每一层返回上来的时候再+1。

这题如果按最大深度那样去想就做不出来了。因为一旦按那个套路去做,就没想到这种情况。
如果按之前那个套路,递归去算左右子树的最小高度,那在第一个节点,就会直接取到min,这显然不是想要的答案。那显然这个时候就要把这种情况给排除。
排除的方式就是做判断:
1.如果有一个节点为null了,那么你要判断能不能往下走。两个节点都为null了你才可以停。
2.两个节点都不为null,那就计算左右子树最小高度。
请添加图片描述
在递归的过程中,计算左右最小深度。然后进行上面所说的特判。

class Solution {
    public int minDepth(TreeNode root) {
        if(root==null){
        //递归出口,能到这说明后面没路走了
            return 0;
        }
        //计算左右子树最小深度
        int leftDepth = minDepth(root.left);
        int rightDepth = minDepth(root.right);
        //对上面说的特殊情况做判断,判断属于哪种
        if(root.left==null){
            return rightDepth+1;
        }
        if(root.right==null){
            return leftDepth+1;
        }
		//都不是上面说的两种情况,那就是二者去min。
        return Math.min(leftDepth,rightDepth)+1;
    }
}

226 翻转二叉树

上来还是宏观上考虑,就是节点的左右子树不停的做swap操作。如果节点空了就退出。

想到了就直接这么写。

/**
 * 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 TreeNode invertTree(TreeNode root) {
        dfs(root);
        return root;
    }
	//每个节点都做reverse处理,然后下一层还是对左右子树做同样的处理。
    public void dfs(TreeNode root){
        if(root==null){
            return;
        }
        reverse(root);
        dfs(root.left);
        dfs(root.right);
    }
	//封装的一个函数。
    public void reverse(TreeNode root){
        TreeNode temp = root.left;
        root.left = root.right;
        root.right = temp;
    }
}

101 对称二叉树

这题看了这个图就知道递归过程中在干嘛了。请添加图片描述
向下的过程可以发现,一直在比较左节点的左孩子是否和右节点的右孩子相等,右节点的左孩子是否和左节点的右孩子相等。所以每层向下一直在做这件事。

/**
 * 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 boolean isSymmetric(TreeNode root) {
    //特判
        if(root==null){
            return true;
        }
        //开始递归
        return dfs(root.left,root.right);
    }

    boolean dfs(TreeNode left,TreeNode right){
    //递归出口
        if(left==null && right == null){
            return true;
        }
        //能走到这里,上一个判断没有出去,说明必有一为null。所以返回false
        if(left==null || right == null){
            return false;
        }
		//走到这说明两个都不为null,那就判断值
        if(left.val != right.val){
            return false;
        }
		//往下一层走,就是判断左节点的左孩子,和右节点的右孩子。
        return dfs(left.left,right.right) && dfs(left.right,right.left);
    }
}

100 相同的树

这个更是简单。在递归的过程中,单纯在比较二者左右孩子是否相等。

class Solution {
    public boolean isSameTree(TreeNode p, TreeNode q) {
        if(p==null && q == null){
            return true;
        }
        if(p==null || q==null){
            return false;
        }

        if(p.val != q.val){
            return false;
        }

        return isSameTree(p.left,q.left) && isSameTree(p.right,q.right);
    }
}

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

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

相关文章

Nginx入门到精通三(反向代理1)

下面内容整理自bilibili-尚硅谷-Nginx青铜到王者视频教程 Nginx相关文章 Nginx入门到精通一&#xff08;基本概念介绍&#xff09;-CSDN博客 Nginx入门到精通二&#xff08;安装配置&#xff09;-CSDN博客 Nginx入门到精通三&#xff08;Nginx实例1&#xff1a;反向代理&a…

Linux系统搭建轻量级个人博客VanBlog并一键发布公网远程访问

文章目录 前言1. Linux本地部署2. VanBlog简单使用3. 安装内网穿透4. 创建公网地址5. 创建固定公网地址 前言 今天和大家分享如何在Linux Ubuntu系统搭建一款轻量级个人博客VanBlog&#xff0c;并结合cpolar内网穿透软件生成公网地址&#xff0c;轻松实现随时随地远程访问本地…

Python与自动化脚本编写

Python与自动化脚本编写 Python因其简洁的语法和强大的库支持&#xff0c;成为了自动化脚本编写的首选语言之一。在这篇文章中&#xff0c;我们将探索如何使用Python来编写自动化脚本&#xff0c;以简化日常任务。 一、Python自动化脚本的基础 1. Python在自动化中的优势 Pyth…

内存RAS技术介绍:内存故障预测

故障预测是内存可靠性、可用性和服务性&#xff08;RAS&#xff09;领域中的一个重要方面&#xff0c;旨在提前识别潜在的不可纠正错误&#xff08;UE&#xff09;&#xff0c;以防止系统崩溃或数据丢失。 4.1 错误日志记录与预测基础 错误一般通过Linux内核模块Mcelog记录到…

1.31、基于长短记忆网络(LSTM)的发动机剩余寿命预测(matlab)

1、基于长短记忆网络(LSTM)的发动机剩余寿命预测的原理及流程 基于长短期记忆网络(LSTM)的发动机剩余寿命预测是一种常见的机器学习应用&#xff0c;用于分析和预测发动机或其他设备的剩余可用寿命。下面是LSTM用于发动机剩余寿命预测的原理和流程&#xff1a; 数据收集&#…

实践之K近邻算法实现红酒聚类

前言 K近邻算法是一种用于分类和回归的非参数统计方法&#xff0c;通过计算样本与训练样本的距离&#xff0c;找出最接近的k个样本进行投票来确定分类结果。算法的基本要素包括K值、距离度量和分类决策规则。 K值决定了邻居的影响程度&#xff0c;距离度量反映了样本间的相似度…

python条件

条件语句 if语句 if...else语句 if...elif...else语句 嵌套 is is 是一个身份运算符&#xff0c;用于比较两个对象的身份&#xff0c;即它们在内存中的地址是否相同。这与比较两个对象是否相等的 运算符不同。 运算符比较的是两个对象的值是否相等。 比较对象 比较基本数据…

npm发布的包如何快速在cnpm上使用

npm发布的包如何快速在cnpm上使用 解决方案 前往淘宝npm镜像官网 搜索插件库并点击同步 等待一分钟即可查看最新版本

C++ 类和对象 赋值运算符重载

前言&#xff1a; 在上文我们知道数据类型分为自定义类型和内置类型&#xff0c;当我想用内置类型比较大小是非常容易的但是在C中成员变量都是在类(自定义类型)里面的&#xff0c;那我想给类比较大小那该怎么办呢&#xff1f;这时候运算符重载就出现了 一 运算符重载概念&…

ts踩坑!vue3中defineEmits接收父组件向子组件传递方法,以及方法所需传的参数及类型定义!

使用说明 1、在子组件中调用defineEmits并定义要发射给父组件的方法 const emits defineEmits([‘foldchange’]) 2、使用defineEmits会返回一个方法&#xff0c;使用一个变量emits(变量名随意)去接收 3、在子组件要触发的方法中&#xff0c;调用emits并传入发射给父组件的方法…

【C语言初阶】探索编程基础:深入理解分支与循环语句的奥秘

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ ⏩收录专栏⏪&#xff1a;C语言 “ 登神长阶 ” &#x1f921;往期回顾&#x1f921;&#xff1a;C语言入门 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀分支与循环语句 &#x1f4d2;1.…

【学习笔记】无人机(UAV)在3GPP系统中的增强支持(十三)-更换无人机控制器

引言 本文是3GPP TR 22.829 V17.1.0技术报告&#xff0c;专注于无人机&#xff08;UAV&#xff09;在3GPP系统中的增强支持。文章提出了多个无人机应用场景&#xff0c;分析了相应的能力要求&#xff0c;并建议了新的服务级别要求和关键性能指标&#xff08;KPIs&#xff09;。…

Kafka:Kafka详解

Kafka 消息中间件 区别于rabbitmq,kafka更适用于量级较大的数据(100w级),主要在大数据领域使用 Kafka介绍 一个分布式流媒体平台,类似于消息队列或企业消息传递系统 Kafak的结构如下 producer:发布消息的对象 topic:Kafak将消息分门别类,每类的消息称为一个主题(Topic) …

《0基础》学习Python——第十一讲__时间函数

一、时间函数是Python中的内置函数和模块&#xff0c;用于处理日期和时间相关的操作。以下是常用的时间函数的种类和用法&#xff1a; 1、time.time()&#xff1a;返回当前时间的时间戳。 时间戳&#xff08;timestamp&#xff09;是一种表示日期和时间的方式&#xff0c;它是一…

高频面试题基本总结回顾4(含笔试高频算法整理)

目录 一、基本面试流程回顾 二、基本高频算法题展示 三、基本面试题总结回顾 &#xff08;一&#xff09;Java高频面试题整理 &#xff08;二&#xff09;JVM相关面试问题整理 &#xff08;三&#xff09;MySQL相关面试问题整理 &#xff08;四&#xff09;Redis相关面试…

使用 SSH 通过 VS Code 连接企业服务器并拉取 Git 仓库代码的指南

文章目录 前言一、SSH 是什么&#xff1f;1.1 SSH 的主要特性和用途1.2 SSH 的工作原理 二、 为什么使用 SSH 而不是 HTTPS三、使用步骤3.1 生成 SSH 密钥3.2 配置 VS Code 远程连接3.3 通过 SSH 克隆 Git 仓库3.4 安装必要的组件 总结 前言 在现代软件开发中&#xff0c;远程…

Sentinel-1 Level 1数据处理的详细算法定义(四)

《Sentinel-1 Level 1数据处理的详细算法定义》文档定义和描述了Sentinel-1实现的Level 1处理算法和方程,以便生成Level 1产品。这些算法适用于Sentinel-1的Stripmap、Interferometric Wide-swath (IW)、Extra-wide-swath (EW)和Wave模式。 今天介绍的内容如下: Sentinel-1 L…

鸿蒙语言基础类库:【@ohos.data.storage (轻量级存储)】

轻量级存储 轻量级存储为应用提供key-value键值型的文件数据处理能力&#xff0c;支持应用对数据进行轻量级存储及查询。数据存储形式为键值对&#xff0c;键的类型为字符串型&#xff0c;值的存储数据类型包括数字型、字符型、布尔型。 说明&#xff1a; 开发前请熟悉鸿蒙开发…

红色文化3D虚拟数字展馆搭建意义深远

在房地产与土地市场的浪潮中&#xff0c;无论是新城规划、乡村振兴&#xff0c;还是商圈建设&#xff0c;借助VR全景制作、虚拟现实和web3d开发技术打造的全链条无缝VR看房新体验。不仅极大提升了带看与成交的转化率&#xff0c;更让购房者足不出户&#xff0c;即可享受身临其境…

前端Vue组件化实践:自定义轮播图组件的探索与应用

在前端开发领域&#xff0c;随着业务逻辑的不断丰富和系统规模的日益扩大&#xff0c;传统的开发方式逐渐暴露出种种弊端。其中&#xff0c;最突出的问题之一便是修改一个小的功能或细节可能导致整个系统的逻辑调整&#xff0c;造成开发效率低下和维护困难。为了应对这些挑战&a…