java算法day20

news2024/9/23 3:13:30

java算法day20

  • 701.二叉搜索树中的插入操作
  • 450.删除二叉搜索树中的节点
  • 108 将有序数组转换为二叉搜索树

本次的题目都是用递归函数的返回值来完成,多熟悉这样的用法,很方便。
其实我感觉,涉及构造二叉树的题目,用递归函数的返回值来做比较方便。每一层涉及对本层的构造,本层的操作结束后,是通过root.left = dfs(root.left,…)这样的方式来递归。
通过这种方式,到最后一层递归好之后,向上返回,这样树就构建起来了。

701.二叉搜索树中的插入操作

本题的特点是在递归出口。而又由这个递归出口,决定了递归的过程中应该干什么。

核心思路:
按BST的方式进行向下搜索,遇到空的位置就进行插入节点。


难点:
这个处理方式很重要。之前我想的是我干脆弄一个pre节点,这样方便我进行插入。但是这样逻辑就很难写。


所以就只能从递归构造左右子树的角度来做。
我说的构造就是这样
root.left = ?
root.right = ?
这样的方式。这样一旦遇到空,那么创建新节点,返回给上一层。这样root.left或者root.right就直接完成构造了。

所以就按这样的思路来。然后往下搜的时候肯定按BST的性质来往下递归。一旦当前节点大于root.val那么递归右子树。一旦往下层一走刚好碰到null,那么创建新节点,这个创建的新节点刚好就符合规则,挂到了这个正确的位置上。

所以说这样的递归方式已经决定好添加的这个节点的位置了,就等着到这个地方之后进行新节点的 创建。

class Solution {
    public TreeNode insertIntoBST(TreeNode root, int val) {
    	//递归出口
    	//root为空,表示走到底了,按BST的性质,这个地方正式新节点的所在地,所以返回给上一层
        if(root==null){
            TreeNode newNode = new TreeNode(val);
            return newNode;
        }
		
		//按BST的性质进行往下搜索
		//但是这里的特点是,不断的构造,最后返回给上一层。是以构造的角度来看
        if(val>root.val){
            root.right = insertIntoBST(root.right,val);
        }else{
            root.left = insertIntoBST(root.left,val);
        }

        return root;
        
    }
}

难点就在这种以构造左右子树的角度的题做少了,可能想得到,但是写不出。


解法2:pre指针的思想

我一开始想用的这种做法,但是pre我处理的并不好。
所以从这个题解来学习处理pre节点。
注意这个题是迭代法,也就是用循环了。

class Solution {
    public TreeNode insertIntoBST(TreeNode root, int val) {
    //注意这个并不是递归出口,这只是特判
        if (root == null) return new TreeNode(val);
        //pre初始化为root。
        //newRoot是用来后面构造好了返回结果的。
        TreeNode newRoot = root;
        TreeNode pre = root;
        //我个人感觉,怎样才能使得最后的时候,pre和cur一前一后?
        //技巧:pre的状态变更在一开是就更新为cur,而cur的变更则是在做完操作之后才变更。而且要针对cur做循环跳出的判断,否则到最后的时候,cur又跳进去了,pre会和cur同步。这样cur才会比pre多走一步。
        //内部的逻辑就是BST的向下搜索过程
        while (root != null) {
            pre = root;
            if (root.val > val) {
                root = root.left;
            } else if (root.val < val) {
                root = root.right;
            } 
        }
        //这里就是判断这个新节点是挂在左边还是右边,因为cur只管遇到null就停下来
        if (pre.val > val) {
            pre.left = new TreeNode(val);
        } else {
            pre.right = new TreeNode(val);
        }

        return newRoot;
    }
}

450.删除二叉搜索树中的节点

这个就像手算删除二叉树节点的过程。删的时候判断属于哪种类型。
这里就把所有类型做一个判断,符合哪种就完成哪种删除,这就是本题的思路。
有以下五种情况:

第一种情况:没找到删除的节点,遍历到空节点直接返回了
找到删除的节点
第二种情况:左右孩子都为空(叶子节点),直接删除节点, 返回NULL为根节点
第三种情况:删除节点的左孩子为空,右孩子不为空,删除节点,右孩子补位,返回右孩子为根节点
第四种情况:删除节点的右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子为根节点
第五种情况:左右孩子节点都不为空,则将删除节点的左子树头结点(左孩子)放到删除节点的右子树的最左面节点的左孩子上,返回删除节点右孩子为新的根节点。

第五种比较抽象,但是这就是调整的方式,可以看看下图。
根据BST的性质,就是要把左子树挂到右子树最左下,才符合BST的性质。
请添加图片描述

class Solution {
    public TreeNode deleteNode(TreeNode root, int key) {
        //这个情况就属于没搜到,到了最底下就返回了,一直把null带给最顶层。
        if(root==null){
            return root;
        }

        //每到一个节点就先做判断,是不是要删的节点,不是再按BST往下层走
        if(root.val==key){
            //开始分情况讨论了,先拿下比较简单的情况
            if(root.left == null){
                //删除的节点,左子树为空,那么就把右子树挂上去,即把右子树返回给上层
                return root.right;
            }else if(root.right==null){
                return root.left;
            }else{
                TreeNode cur = root.right;
                while(cur.left!=null){
                    cur = cur.left;
                }
                //此时已经到右子树的最左了,把root的左子树直接挂到cur的左子树上
                cur.left = root.left;
                //然后删除当前节点,root直接指向root.right就完成删除了
                root = root.right;
                //这里就完成了删除操作,然后返回结果。
                return root;
            }
        }

        //BST向下搜索构建的过程
        //这里一定要想清楚,因为是BST,所以往下就一个方向,所以往下递归构建就一个方向,
        //在每一层要么往左构建,要么往右构建。
        //key>root.val那往右进行递归到下一层,构建本层的root.right
        if(key>root.val){
            root.right = deleteNode(root.right,key);
        }else if(key<root.val){
            root.left = deleteNode(root.left,key);
        }
        //这里已经是回来的逻辑了,所以构建的结果要返回给上一层。
        return root;
    }
}

108 将有序数组转换为二叉搜索树

题目一旦涉及到数组,那么根据经验,尽量不要重新定义左右区间数组,而是用下标来操作原数组。

本题有个要点,那就要满足平衡二叉搜索树。
因为对于有序数组而言,直接按顺序建一个线性树,那也满足二叉搜索树。
请添加图片描述
那要满足平衡二叉树那该怎么办?
本质是在找分割点。
递归的过程种,每次分割点取数组中间节点,然后递归构建左右子树就行了。
所以一层的子区间可以通过传递下标来完成表示。

class Solution {
    public TreeNode sortedArrayToBST(int[] nums) {
        return traversal(nums,0,nums.length-1);
    }

    TreeNode traversal(int[] nums,int left,int right){
    //递归出口,也就是递归构造的过程是区间不断收缩的过程,收缩完了就代表该位置没有节点构造。
        if(left>right){
            return null;
        }
        //每次取中间节点作为分割点
        int mid = left+(right-left)/2;
        //构造新节点
        TreeNode root = new TreeNode(nums[mid]);
        
        //递归构造左右子树,传递子区间。因为节点要取新的区间的中间节点。
        //这里显然是左闭右闭写法。
        root.left = traversal(nums,left,mid-1);
        root.right = traversal(nums,mid+1,right);
        //构造完了就返回,从底下返回来上,就全都构建好了。
        return root;


    }
}

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

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

相关文章

2024 年 100 大数据科学面试问答

2024 年 100 大数据科学面试问答 一、说明 数据科学是一个快速发展的领域&#xff0c;它正在改变组织根据数据理解和做出决策的方式。因此&#xff0c;公司越来越多地寻求聘请数据科学家来帮助他们理解数据并推动业务成果。这导致了对数据科学家的高需求&#xff0c;这些职位的…

TikTok矩阵:从0到百万粉丝的秘密!

在TikTok这个充满活力与创意的短视频平台上&#xff0c;每一位创作者都怀揣着成为耀眼明星的梦想。如何让自己的作品脱颖而出&#xff0c;吸引并留住万千粉丝的目光&#xff0c;成为了每一位创作者亟待解决的问题。此时&#xff0c;TikTok矩阵策略便如同一盏明灯&#xff0c;照…

【BES2500x系列 -- RTX5操作系统】系统启动流程 -- boot loader概念讲解 --(九)

&#x1f48c; 所属专栏&#xff1a;【BES2500x系列】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#x1f49…

力扣高频SQL 50题(基础版)第七题

文章目录 力扣高频SQL 50题&#xff08;基础版&#xff09;第七题1068. 产品销售分析 I题目说明思路分析实现过程准备数据&#xff1a;实现方式&#xff1a;结果截图:总结&#xff1a; 力扣高频SQL 50题&#xff08;基础版&#xff09;第七题 1068. 产品销售分析 I 题目说明 …

mysql + Oracle

eg627. 变更性别 Salary 表&#xff1a; ----------------------- | Column Name | Type | ----------------------- | id | int | | name | varchar | | sex | ENUM | | salary | int | ----------------------- id 是这个表…

eclipse 没有war file 选项 不能导入和导出war包

1 eclipse打包war,项目右键 2 安装Web和Java EE插件, 在Eclipse中选择Help菜单&#xff0c;然后选择Install New Software。在Work with下拉菜单中选择All Available Sites&#xff0c;然后选择Web, XML, Java EE and OSGi Enterprise Development进行安装。完成安装后&#xf…

海康视频WEB插件

引入相关依赖 index.html <script src"/video/web-control_1.2.5.min.js"></script> <script src"/video/jquery-1.12.4.min.js" type"text/javascript"></script> <script src"/video/jsencrypt.min.js" …

使用LSTM完成时间序列预测

c 在本教程中&#xff0c;我们将介绍一个简单的示例&#xff0c;旨在帮助初学者入门时间序列预测和 PyTorch 的使用。通过这个示例&#xff0c;你可以学习如何使用 LSTMCell 单元来处理时间序列数据。 我们将使用两个 LSTMCell 单元来学习从不同相位开始的正弦波信号。模型在…

黑马程序员2024最新SpringCloud微服务开发与实战 个人学习心得、踩坑、与bug记录Day4 重置版 全网最全最快

你好,我是Qiuner. 为帮助别人少走弯路和记录自己编程学习过程而写博客 这是我的 github https://github.com/Qiuner ⭐️ gitee https://gitee.com/Qiuner &#x1f339; 如果本篇文章帮到了你 不妨点个赞吧~ 我会很高兴的 &#x1f604; (^ ~ ^) 想看更多 那就点个关注吧 我会…

python3.10.4——windows环境安装

python下载官网&#xff1a;https://www.python.org/downloads/ 如果安装在C盘&#xff0c;需要右键→选择“以管理员身份运行” 勾选2个按钮&#xff0c;选择自定义安装 全部选择&#xff0c;点击Next 更改安装路径 命令行检查python是否安装成功&#xff1a; 出现版本号说明…

通俗地理解主动元数据管理

元数据管理&#xff0c;是企业开展数据管理的核心基础&#xff0c;内容涉及元数据的创建&#xff0c;确定需要捕获哪些元数据&#xff0c;通过哪些工具和流程进行创建&#xff0c;继而将元数据妥善存储&#xff0c;保障安全性和可访问性&#xff0c;并不断更新维护&#xff0c;…

vue3前端开发-小兔鲜项目-使用逻辑函数拆分业务模块

vue3前端开发-小兔鲜项目-使用逻辑函数拆分业务模块&#xff01;其实就是把一些单独的业务代码组成一个js文件。抽离出去后&#xff0c;方便后面的维护。 如图&#xff0c;在一级分类下面新建一个文件夹。composables里面新建2个js文件。 分别封装之前的分类&#xff0c;和ban…

Electron 企业级开发通信与本地存储实用解决方案

背景 之前写了一篇Electron通信的方式&#xff0c;讲述了一下三者之间的通信机制&#xff0c;比较恶心&#xff0c;后来发现有个electron/remote&#xff0c; Electron 渲染进程直接调用主进程的API库electron/remote引用讲解-CSDN博客文章浏览阅读58次。remote是个老库&…

将mars3D导入自己的项目中

文章目录 Mars3D官方文档 一、打开自己的vite项目二、创建场景配置文件1.json文件路径 public\config\config.json2.创建组件定义文件路径 src\components\mars-work\mars-map.vue三、demo中引入四、必要样式 依赖文件 总结 Mars3D官方文档 一、打开自己的vite项目 我创建了一…

【Linux】安装Nacos-单机版

一、摘要 单机模式又称单例模式, 拥有所有Nacos的功能及特性&#xff0c;具有极易部署、快速启动等优点。但无法与其他节点组成集群&#xff0c;无法在节点或网络故障时提供高可用能力。单机模式同样可以使用内置Derby数据库&#xff08;默认&#xff09;和外置数据库进行存储…

爆赞!终于有大佬把网络安全零基础入门教程给讲明白了!

网络安全的一个通用定义指网络信息系统的硬件、软件及其系统中的数据受到保护&#xff0c;不因偶然的或者恶意的破坏、更改、泄露&#xff0c;系统能连续、可靠、正常地运行&#xff0c;服务不中断。网络安全简单的说是在网络环境下能够识别和消除不安全因素的能力。 网络安全…

探索智能本质:技术智能的演进趋势

在人工智能的浪潮中&#xff0c;我们常常被各种技术术语和概念所包围&#xff0c;但智能的本质究竟是什么&#xff1f;香港大学计算与数据科学学院院长马毅教授&#xff0c;在第三届「知乎 AI 先行者沙龙」上的演讲&#xff0c;为我们提供了全新视角。香港大学马毅&#xff1a;…

vue3 vite 引入包报错 无法找到模块“lib-flexible/flexible.js”的声明文件

文章目录 vue3 vite 引入包报错解决方法 1解决方法 2 vue3 vite 引入包报错 无法找到模块“lib-flexible/flexible.js”的声明文件。“d:/mine/web面试/video-demo/node_modules/lib-flexible/flexible.js”隐式拥有 "any" 类型。尝试使用 npm i --save-dev types…

《昇思25天学习打卡营第23天 | 基于MobileNetv2的垃圾分类》

《昇思25天学习打卡营第23天 | 基于MobileNetv2的垃圾分类》 目录 《昇思25天学习打卡营第23天 | 基于MobileNetv2的垃圾分类》1、实验目的2、MobileNetv2模型原理介绍3、实验环境4、数据处理4.1数据准备下载data_en数据集 4.2数据加载将模块导入&#xff0c;具体如下&#xff…

k8s 公共服务

修改named.conf。修改第13行和第21行 下面是 named.rfc1912 修改位置&#xff0c;在最后 所以用cp -p 复制文件&#xff0c;保留权限 nslookup 回车&#xff0c;server是看哪个dns 在起作用 dns服务器要配置给所有公共服务节点和 k8s 节点 就在网络文件加个DNS2就行了&…