代码随想录算法训练营第二十二天 | LeetCode 669. 修剪二叉搜索树、108. 将有序数组转换为二叉搜索树、538. 把二叉搜索树转换为累加树

代码随想录算法训练营第二十二天 | LeetCode 669. 修剪二叉搜索树、108. 将有序数组转换为二叉搜索树、538. 把二叉搜索树转换为累加树

文章链接:修剪二叉搜索树        将有序数组转换为二叉搜索树        把二叉搜索树转换为累加树

视频链接:修剪二叉搜索树        将有序数组转换为二叉搜索树        把二叉搜索树转换为累加树

目录

代码随想录算法训练营第二十二天 | LeetCode 669. 修剪二叉搜索树、108. 将有序数组转换为二叉搜索树、538. 把二叉搜索树转换为累加树

1. LeetCode 669. 修剪二叉搜索树

1.1 思路

1.2 代码

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

2.1 思路

2.2 代码

3. LeetCode 538. 把二叉搜索树转换为累加树

3.1 思路

3.2 代码


1. LeetCode 669. 修剪二叉搜索树

1.1 思路

  1. 在上面450. 删除二叉搜索树中的节点这题中有一种情况我们是把删除节点的右子树返回给删除节点的父节点,让父节点直接指向被删节点的右子树。
  2. 递归函数的参数和返回值:就是本题给的函数,返回的是修剪完后新的二叉树的根节点,参数是root,左右边界low和high
  3. 终止条件:如果遍历到null,就return null;
  4. 常见误区:如果root的值比low小或者比high大就返回null,如果按照这样删除,那么root的父节点就直接指向空了,如果root还有左右孩子就直接无法连接了。
  5. 正确思路:如果发现当前节点的值比左边界小或者比右边界大,其右子树是可能符合边界条件的,就应该先把右子树接着遍历
  6. 以下是单层递归的逻辑:
  7. 判断如果root的值比low小,就接着向右遍历,right=函数(root.right, low, high),含义是把被删节点的右子树修剪完以后返回给被删节点的父节点,然后返回right;这里判断后不能直接return root.right,因为root的右子树不一定完全符合题目的边界要求,因此需要遍历。
  8. 判断如果root的值比high大,就接着向左遍历,left=函数(root.left, low, high),含义是把被删节点的左子树修剪完以后返回给被删节点的父节点,然后返回left;这里判断后不能直接return root.left,因为root的左子树不一定完全符合题目的边界要求,因此需要遍历。
  9. 接着就是左root.left=函数(root.left, low, high);然后是右root.right=函数(root.right, low, high);return root。root在上面处理过了

1.2 代码

//
class Solution {public TreeNode trimBST(TreeNode root, int low, int high) {if (root == null) {return null;}if (root.val < low) {return trimBST(root.right, low, high);}if (root.val > high) {return trimBST(root.left, low, high);}// root在[low,high]范围内root.left = trimBST(root.left, low, high);root.right = trimBST(root.right, low, high);return root;}
}

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

2.1 思路

  1. 关于构造二叉树,在106. 从中序与后序遍历序列构造二叉树这题中讲解过,整体思路是先选取一个中间节点,然后将数组分为左区间和右区间,递归遍历左区间构造左子树和遍历右区间构造右子树。
  2. 本题中,也只有选取数组中间的数作为中间节点,左区间和右区间数量才相同,然后左区间也选中间然后分割左右区间,右区间也选中间然后分割左右区间。如果数组长度是偶数,中间有两个数,其实选哪个都可以,只是取靠左的那个数和靠右的那个数构造出来的树结构不一样而已。
  3. 递归函数的参数和返回值:参数是nums数组,左边界,右边界。返回值就是构造出来的二叉树的根节点。定义区间的时候是左闭右闭还是左闭右开,这点要注意很重要!我们要全部统一定义,这里我定义的是左闭右闭的区间
  4. 终止条件:如果left>right就是一个非法区间了,因为我这里定义的是左闭右闭,left==right是一个合法区间,只是这里是只有一个节点,那可能是叶子节点,但也符合题意的,因此我们就left>right时返回null即可
  5. 单层递归的逻辑:中间节点的位置mid=(left+right)/2;然后是构造二叉树,root=新的节点,把nums[mid]赋值给它;然后root.left=函数(nums, left, mid-1),因为是左闭右闭的区间,所以mid要减1,mid-1这个位置是包含右边界的。这个函数的含义是在这个数组下,下标是left和mid-1所构造的二叉树的根节点返回过来给root的左子树;然后root.right=函数(nums, mid+1, right),因为是左闭右闭的区间,所以mid要+1,mid+1这个位置是包含左边界的。这个函数的含义是在这个数组下,下标是mid+1和right所构造的二叉树的根节点返回过来给root的右子树。然后返回root即可

2.2 代码

//
class Solution {public TreeNode sortedArrayToBST(int[] nums) {TreeNode root = traversal(nums, 0, nums.length - 1);return root;}// 左闭右闭区间[left, right]private TreeNode traversal(int[] nums, int left, int right) {if (left > right) return null;int mid = left + ((right - left) >> 1);TreeNode root = new TreeNode(nums[mid]);root.left = traversal(nums, left, mid - 1);root.right = traversal(nums, mid + 1, right);return root;}
}

3. LeetCode 538. 把二叉搜索树转换为累加树

3.1 思路

  1. 本题的累加方式是右中左,也就是反中序遍历,按照中序遍历的方式从右开始加就看懂了
  2. 本题我们要从后往前加,如何从最大的节点开始倒序遍历呢?也就是右中左。那如何当前节点跟前一个节点相加呢?双指针!root指向当前节点,pre指向前一个节点的值,然后逐渐相加,逐渐往回遍历
  3. 递归函数的参数和返回值:要先定义一个全局变量int pre=0,直接定义成值就好,不用是节点,最开始root是指向最大的节点,pre=0,root.val+=pre,最开始是不变的。定义个新函数,返回值void,因为本题不需要返回值返回什么,参数就是传入根节点
  4. 终止条件:遇到空节点就return了
  5. 单层递归的逻辑:因为是右中左,因此先往右遍历,travelsal(root.right);然后就是中的逻辑,就是root.val+=pre,然后pre=root.val,就更新pre,能让下一次root指向下一个节点时,pre能表示root的前一个节点的值;然后是再往左遍历,travelsal(root.left)。最后return即可

3.2 代码

//
class Solution {int sum;public TreeNode convertBST(TreeNode root) {sum = 0;convertBST1(root);return root;}// 按右中左顺序遍历,累加即可public void convertBST1(TreeNode root) {if (root == null) {return;}convertBST1(root.right);sum += root.val;root.val = sum;convertBST1(root.left);}
}

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

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

相关文章

启动Spring Boot项目

介绍启动运行Spring Boot项目打包的jar 1、使用java -jar命令启动项目 java -jar project.jar 执行效果&#xff1a; 使用java -jar 文件名.jar启动项目&#xff0c;项目在前台运行&#xff0c;项目运行的日志将打印在当前控制台上&#xff0c;若退出当前控制台&#xff0c…

函数调用:为什么会发生stack overflow?

在开发软件的过程中我们经常会遇到错误&#xff0c;如果你用 Google 搜过出错信息&#xff0c;那你多少应该都访问过Stack Overflow这个网站。作为全球最大的程序员问答网站&#xff0c;Stack Overflow 的名字来自于一个常见的报错&#xff0c;就是栈溢出&#xff08;stack ove…

微信小程序生成海报

效果: js1: const cloudHelper = require(../../../helper/cloud_helper.js);async function config1({cover,title,desc,qr,bg = }) {var qr1 ="images/qr.png"var qr2 ="https://636c-cloud1-0gu29f2j63906b7e-1319556650.tcb.qcloud.la/activitycomm/setu…

web入门---tomcat请求响应

Tomcat 介绍 Web 服务器是一个软件程序&#xff0c;对 HTTP协议的操作进行封装&#xff0c;使得不必直接对协议进行操作&#xff0c;让 web 开发更加便捷。主要功能是“提供网上信息浏览服务”。 下载 tomcat 演示说明 这里有一个示例直接双击打开 index.html但是这个“打开…

OK3568 UBUNTU 安装使用I2C-TOOLS

1. 安装 sudo apt-get update sudo apt-get install i2c-tools 使用I2Ctools 参考&#xff1a;https://blog.csdn.net/anyuliuxing/article/details/106382827 i2c-tools 是一组用于在Linux系统中进行I2C&#xff08;Inter-Integrated Circuit&#xff09;总线设备操作和调试…

3.7 Android eBpf Hello World调试(一)

写在前面 tracepoint是Linux内核中预定义的静态探测点,分布于内核各个子系统中。每个tracepoint通常包含开关-enable,过滤器-filter等。如下是/sys/kernel/tracing/events/sched子系统中支持的各种tracepoint事件: coral:/sys/kernel/tracing/events/sched $ ls core_ctl_…

RabbitMQ部署指南

大家好我是苏麟今天安装RabbitMQ. 单机部署 我们在Centos7虚拟机中使用Docker来安装。 下载镜像 在线拉取: 最新版本 docker pull rabbitmq 3-managenment版本 docker pull rabbitmq:3-management这两个下载一个就可以 安装MQ docker run -e RABBITMQ_DEFAULT_USERroo…

Cadence 设计实践笔记-小哥allegro 2层板笔记

本章节主要跟着B站PCB入门首选视频-小哥Cadence Allegro 2层板视频,结合自己的实践一步步完成一个完整的PCB板的设计。 视频链接地址: PCB入门首选视频-小哥Cadence Allegro 2层板视频_哔哩哔哩_bilibili 规范建立文件夹 建立八个文件夹 DATASHEET 主要存放设计项目…

第十二章 磁盘管理

1. 磁盘简介 1.1. 概念 硬盘是由一片或多篇带有磁性的铝合金制的盘片构成&#xff0c;是 一种大容量、永久性的外部存储设备 组成&#xff1a;盘片、马达驱动、缓存、控制电路、接口 图&#xff1a; 1.2. 逻辑结构 磁道&#xff1a;由内到外的同心圆 扇区&#xff1a;半径组成…

JVM基础:初识JVM

IDE&#xff1a;IntelliJ IDEA 2022.1.3 x64 操作系统&#xff1a;win10 x64 位 家庭版 文章目录 一、JVM是什么&#xff1f;二、JVM有哪些功能&#xff1f;2.1 解释和运行2.2 内存管理2.3 即时编译 三、有哪些常见的JVM&#xff1f;3.1 常见JVM3.2 Java虚拟机规范3.3 HotSpot的…

力扣每日一题136:只出现一次的数字

题目描述&#xff1a; 给你一个 非空 整数数组 nums &#xff0c;除了某个元素只出现一次以外&#xff0c;其余每个元素均出现两次。找出那个只出现了一次的元素。 你必须设计并实现线性时间复杂度的算法来解决此问题&#xff0c;且该算法只使用常量额外空间。 示例 1 &#…

C++入门 第一篇(C++关键字, 命名空间,C++输入输出)

目录 1. C关键字 2. 命名空间 2.1 命名空间定义 2.2命名空间的使用 命名空间的使用有三种方式&#xff1a; 1.加命名空间名称及作用域限定符 2.使用using将命名空间中某个成员引入 3.使用using namespace 命名空间名称 引入 3. C输入&输出 4.缺省函数 4.1 缺省参…

记一次Hbase2.1.x历史数据数据迁移方案

查看待迁移的表 list_namespace_tables vaas_dwm2. 制作待迁移表“DWM_TRIP_PART”的快照 snapshot vaas_dwm:DWM_TRIP_PART,dwm_trip_part_snapshot3. 统计待迁移表数据总数 hbase org.apache.hadoop.hbase.mapreduce.RowCounter vaas_dwm:DWM_TRIP_PART

使用postMan调试接口出现 Content type ‘multipart/form-data;charset=UTF-8‘ not supported“

使用postMan调试接口出现 Content type multipart/form-data&#xff1b;charsetUTF-8 not supported" 问题原因解决方案 最近好久没写springboot项目了&#xff0c;然后写了一个添加用户的接口&#xff0c;使用postman测试时出现了问题。如下图&#xff1a; org.springfr…

HttpServletRequest对象与RequestDispatcher对象

一、HttpServletRequest对象 1.介绍 在Servlet API中&#xff0c;定义了一个HttpServletRequest接口&#xff0c;它继承自ServletRequest接口&#xff0c;专门用来封装HTTP请求消息。由于HTTP请求消息分为请求行、请求消息头和请求消息体三部分&#xff0c;因此&#xff0c;在…

Gin 中的 Session(会话控制)

Session 介绍 session和cookie实现的底层目标是一致的,但是从根本而言实现的方法是不同的; session 是另一种记录客户状态的机制, 不同的是 Cookie 保存在客户端浏览器中,而 session保存 在服务器上 ; Session 的工作流程 当客户端浏览器第一次访问服务器并发送请求时,服…

【LVGL】SquareLine Studio入门基础操作

1.SquareLine Studio基础 在这篇文章中将介绍SquareLine Studio的基础操作、解释如何加载一个项目、布局结构。    启动软件后,可以加载之前的项目、创建项目、加载一个示例。    这里以打开示例audio_mixer为例,可以双击该项目打开或者选中该项目点击右下角的【创建】按…

Hadoop3教程(一):Hadoop的定义、组成及全生态概览

文章目录 &#xff08;1&#xff09;定义1.1 发展历史1.2 三大发行版本1.3 Hadoop的优势1.4 Hadoop的组成 &#xff08;13&#xff09;HDFS概述&#xff08;14&#xff09;Yarn架构&#xff08;15&#xff09;MapReduce概述&#xff08;16&#xff09; HDFS、YARN、MapReduce三…

使用 puppeteer 加载 html 文件来运行 js 文件

遇到一个需求, 在浏览器环境下来运行 js sdk 文件, 这个 js 文件是不能运行在 nodejs 环境下的; 所以通过 puppeteer 无头浏览器来运行代码获取对应的结果。 首先是安装插件 puppeteer&#xff0c;然后创建一个项目, 我这里是express&#xff1b; 这里是主要的代码。 const p…

【云原生之Docker实战】使用Docker部署WBO在线协作白板

【云原生之Docker实战】使用Docker部署WBO在线协作白板 一、WBO介绍1.1 WBO简介1.2 WBO特点二、本地环境介绍2.1 本地环境规划2.2 本次实践介绍三、本地环境检查3.1 检查Docker服务状态3.2 检查Docker版本3.3 检查docker compose 版本四、构建WBO镜像4.1 下载WBO源码4.2 构建WB…