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

 题目与题解

参考资料:二叉树总结

669. 修剪二叉搜索树

题目链接:669. 修剪二叉搜索树

代码随想录题解:​​​​​​​669. 修剪二叉搜索树

视频讲解:你修剪的方式不对,我来给你纠正一下!| LeetCode:669. 修剪二叉搜索树_哔哩哔哩_bilibili

解题思路:

        有了昨天删除二叉搜索树节点的题目为基础,这一题只是从删除一个特定节点改为删除多个符合条件的节点,做法是类似的。

        这里还是用递归做,入参是根节点,low和high,终止条件是节点为空,返回值为完成删除后的根节点。递归体为:如果根节点的值在范围内,则分别对其左右子树进行递归,得到新的左右子树根节点;如果根节点的值在范围外,分情况讨论:如果该节点是叶子节点,直接返回null;如果左子树为空,或者其值小于low,则对右子树进行递归,并让根节点等于递归后的结果;如果右子树为空,或者其值大于high,则对左子树进行递归,并让根节点等于递归后的结果。

class Solution {
    public TreeNode trimBST(TreeNode root, int low, int high) {
		if (root == null) return null;
		if (root.val >= low && root.val <= high) {
			root.left = trimBST(root.left, low, high);
			root.right = trimBST(root.right, low, high);
		} else {
			if (root.left == null && root.right == null)
				return null;
			else if (root.left == null || root.val < low) {
				root = trimBST(root.right, low, high);
			} else if (root.right == null || root.val > high){
				root = trimBST(root.left, low, high);
			}
		}
		return root;
    }
}

看完代码随想录之后的想法 

        思路差不多,随想录写的更精简一点。有些代码是可以合并的,比如并不需要在root.val不满足条件时判断左右子树是否为空,直接根据其小于low还是大于high进行下一层的递归即可,并且可以把val不在区间内的情况写在前面,就可以提前return了。

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;
    }
}

遇到的困难

        如何考虑到所有的情况是个难点,好在有昨天的题打底稍微好一些。

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

题目链接:108.将有序数组转换为二叉搜索树

代码随想录题解:108.将有序数组转换为二叉搜索树

视频讲解:构造平衡二叉搜索树!| LeetCode:108.将有序数组转换为二叉搜索树_哔哩哔哩_bilibili

解题思路:

        平衡二叉树的定义是每个节点左右子树的高度差都不大于1,以此达到搜索效率最高的结果。那么在构造的时候,就要尽量让左右子树中含有的节点数量不要相差太大,所以每次把数组最中间的节点当作根节点最好,这样也符合二叉搜索树的要求,即左边的数小于根节点,右边的数大于根节点。

        这里用递归来做,递归入参是有序数组,对应的起始位置low和终止位置high(java不能直接传地址,所以为了不额外new数组就用下标来标识本次递归的数组范围),这里low和high是表示闭区间[low, high],终止条件是low >= high或low小于0或high大于数组最大下标,返回值是建立的二叉搜索树根节点。递归体为:如果low > high,返回空,如果low=high,返回值为nums[low]的新节点,剩下的情况里,将数组一分为二,取得根节点的位置indexRoot = (low+high)/2,再递归的将数组左边的数和右边的数分别传入递归函数,得到左右子树的结构。

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

	public TreeNode sortedArrayToBST(int[] nums, int low, int high) {
		if (low < 0 || high >= nums.length || low > high) return null;
		if (low == high) return new TreeNode(nums[low]);
		int indexRoot = (low + high)/2;
		TreeNode root = new TreeNode(nums[indexRoot]);
		root.left = sortedArrayToBST(nums, low, indexRoot - 1);
		root.right = sortedArrayToBST(nums, indexRoot + 1, high);
		return root;
	}
}

看完代码随想录之后的想法 

        如随想录所说,这题本质就是寻找分割点,分割点作为当前节点,然后递归左区间和右区间。思路是一样的,还是写法上可以精简,low=high的情况可以不用判断,后面的已经涵盖了,并且low和high输入时候已经确定了最大边界,二者不会超出边界,所以不用判断low<0和high > 最大下标。

class Solution {
private:
    TreeNode* traversal(vector<int>& nums, int left, int right) {
        if (left > right) return nullptr;
        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;
    }
public:
    TreeNode* sortedArrayToBST(vector<int>& nums) {
        TreeNode* root = traversal(nums, 0, nums.size() - 1);
        return root;
    }
};

遇到的困难

        边界条件略微需要注意一下,题本身不难。

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

题目链接:538.把二叉搜索树转换为累加树

代码随想录题解:538.把二叉搜索树转换为累加树

视频讲解:普大喜奔!二叉树章节已全部更完啦!| LeetCode:538.把二叉搜索树转换为累加树_哔哩哔哩_bilibili

解题思路:

        凡是遇到二叉搜索树里面,跟升序序列有关的题,都可以先转换成数组去思考如果是有序数组应该怎么做,然后再多加一步遍历二叉搜索树得到有序序列的过程,边遍历边计算出相应的结果。但是自己做的时候被绕晕了,没有写出来。       

看完代码随想录之后的想法 

        这道题变成数组,就是求从最大数到最小数的累加和,比如对于一个有序数组[2, 5, 13],求从后到前的累加数组,也就是[20, 18, 13]。做法也就很明确了,应该按照右中左的顺序来遍历,并累加求和。为此在递归或迭代时,需要记录一下前一个节点的累加和,方便计算当前节点的累加和。

class Solution {
	int pre = 0;
    public TreeNode convertBST(TreeNode root) {
		if (root == null) return root;
		convertBST(root.right);
		root.val += pre;
		pre = root.val;
		convertBST(root.left);
		return root;
    }
}

遇到的困难

        写的时候没有想到可以换成有序数组去思考,一开始想着root的结果就是右边所有节点的和加上val,左边节点则是中间节点加上左边的val,写着写着就乱起来了。凡是遇到二叉搜索树并且要对每个节点进行有序操作的,一定要先看看能不能从升序序列考虑,问题就清晰了。

今日收获

        再次熟悉了一下二叉树的操作,终于结束了。

        一般而言,二叉树的题目规律如下:

  • 涉及到二叉树的构造,无论普通二叉树还是二叉搜索树一定前序,都是先构造中节点。

  • 求普通二叉树的属性,一般是后序,一般要通过递归函数的返回值做计算。

  • 求二叉搜索树的属性,一定是中序了,要不白瞎了有序性了。

  • 涉及到父子节点,一般用前序,方便父节点指向子节点。

        二叉树的题目看起来变化很大,其实无非就是递归,迭代方法,中间根据情况夹杂着回溯,涉及到前中后序三种遍历,万变不离其宗。希望二刷的时候所有方法都能掌握吧。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

新版Idea2023.3.5与lombok冲突、@Data失效

新版idea和lombok冲突&#xff0c;加上Data&#xff0c;其他地方get set也不报错&#xff0c;但是一运行就找不到get set方法。 但是直接使用Getter和Setter可以访问、应该是Data失效了。 解决方法&#xff1a; 看推上介绍是 lombok 与 idea 采集 get 、set 方法的时候所用的技…

成都市酷客焕学新媒体科技有限公司:实现品牌的更大价值!

成都市酷客焕学新媒体科技有限公司专注于短视频营销&#xff0c;深知短视频在社交媒体中的巨大影响力。该公司巧妙地将品牌信息融入富有创意和趣味性的内容中&#xff0c;使观众在轻松愉悦的氛围中接受并传播这些信息。凭借独特的创意和精准的营销策略&#xff0c;成都市酷客焕…

llama-index 结合chatglm3-6B 利用RAG 基于文档智能问答

简介 llamaindex结合chatglm3使用 import os import torch from llama_index.core import VectorStoreIndex, ServiceContext from llama_index.core.callbacks import CallbackManager from llama_index.core.llms.callbacks import llm_completion_callback from llama_ind…

计算机网络链路层

数据链路 链路是从一个节点到相邻节点之间的物理线路&#xff08;有线或无线&#xff09; 数据链路是指把实现协议的软件和硬件加到对应链路上。帧是点对点信道的数据链路层的协议数据单元。 点对点信道 通信的主要步骤&#xff1a; 节点a的数据链路层将网络层交下来的包添…

【three.js】后期处理outlinePass描边实现点击选中物体效果

在 Three.js 中&#xff0c;通过后期处理技术可以实现各种视觉效果&#xff0c;其中包括描边&#xff08;Outline&#xff09;效果&#xff0c;用于突出显示或选中特定物体。本文将重点介绍如何使用 Three.js 中的 OutlinePass 后期处理效果来实现点击选中物体的效果&#xff0…

LeetCode:509斐波那契数 C语言

斐波那契数 &#xff08;通常用 F(n) 表示&#xff09;形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始&#xff0c;后面的每一项数字都是前面两项数字的和。也就是&#xff1a; F(0) 0&#xff0c;F(1) 1 F(n) F(n - 1) F(n - 2)&#xff0c;其中 n > 1给定 n &a…

【笔记】RDD算子操作(Spark基础知识)

持续更新中&#xff01;&#xff01;&#xff01; 目录 一、RDD的创建 1.从本地创建 &#xff08;1&#xff09;本地文件 &#xff08;2&#xff09;hdfs文件&#xff08;先提前创建目录并上传文件&#xff09; 2.从集合创建&#xff08;通过并行集合&#xff08;列表&am…

【C语言基础】:数据在内存中的存储

文章目录 一、整数在内存中的存储二、大小端字节序和字节序判断1. 为什么有大小端&#xff1f;2. 练习 三、浮点数在内存中的存储1. 浮点数的存储1.1 浮点数的存储过程1.2 浮点数取的过程 四、题目解析 书山有路勤为径&#xff0c;学海无涯苦作舟。 创作不易&#xff0c;宝子们…

基于springboot+vue+Mysql的财务管理系统

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

LabVIEW单片机的废气再循环EGR检测系统

LabVIEW单片机的废气再循环EGR检测系统 实现了一种基于LabVIEW和STM32F103VET6单片机的EGR&#xff08;废气再循环&#xff09;检测系统&#xff0c;监测和控制船用二冲程柴油机的EGR运行状态。通过替代传统的NI采集卡&#xff0c;系统不仅降低了成本&#xff0c;同时也提升了数…

es6 Class基本语法和继承

es6 Class基本语法 class的基本语法&#xff1a; ES6 的class只是一个语法糖&#xff0c;它的绝大部分功能&#xff0c;ES5 都可以做到&#xff0c;新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已 传统用构造函数生成实例 function Point(x, y) {th…

Unity AI Navigation自动寻路

目录 前言一、Unity中AI Navigation是什么&#xff1f;二、使用步骤1.安装AI Navigation2.创建模型和材质3.编写向目标移动的脚本4.NavMeshLink桥接组件5.NavMeshObstacle组件6.NavMeshModifler组件 三、效果总结 前言 Unity是一款强大的游戏开发引擎&#xff0c;而人工智能&a…

【漏洞复现】chatgpt pictureproxy.php SSRF漏洞(CVE-2024-27564)

0x01 漏洞概述 ChatGPT pictureproxy.php接口存在服务器端请求伪造 漏洞&#xff08;SSRF&#xff09; &#xff0c;未授权的攻击者可以通过将构建的 URL 注入 url参数来强制应用程序发出任意请求。 0x02 测绘语句 fofa: icon_hash"-1999760920" 0x03 漏洞复现 G…

Machine Learning机器学习之统计分析

目录 前言 机器学习之统计分析 统计学的主要目标包括&#xff1a; 统计学核心概念&#xff1a; 统计基础&#xff1a; 训练误差&#xff1a; 常见的损失函数&#xff1a; 正则化和交叉验证 博主介绍&#xff1a;✌专注于前后端、机器学习、人工智能应用领域开发的优质创作者、秉…

使用pytorch构建一个初级的无监督的GAN网络模型

在这个系列中将系统的构建GAN及其相关的一些变种模型&#xff0c;来了解GAN的基本原理。本片为此系列的第一篇&#xff0c;实现起来很简单&#xff0c;所以不要期待有很好的效果出来。 第一篇我们搭建一个无监督的可以生成数字 (0-9) 手写图像的 GAN&#xff0c;使用MINIST数据…

进阶了解C++(6)——二叉树OJ题

Leetcode.606.根据二叉树创建字符串&#xff1a; 606. 根据二叉树创建字符串 - 力扣&#xff08;LeetCode&#xff09; 难度不大&#xff0c;根据题目的描述&#xff0c;首先对二叉树进行一次前序遍历&#xff0c;即&#xff1a; class Solution { public:string tree2str(Tr…

TheMoon 恶意软件短时间感染 6,000 台华硕路由器以获取代理服务

文章目录 针对华硕路由器Faceless代理服务预防措施 一种名为"TheMoon"的新变种恶意软件僵尸网络已经被发现正在侵入全球88个国家数千台过时的小型办公室与家庭办公室(SOHO)路由器以及物联网设备。 "TheMoon"与“Faceless”代理服务有关联&#xff0c;该服务…

【算法题】三道题理解算法思想--滑动窗口篇

滑动窗口 本篇文章中会带大家从零基础到学会利用滑动窗口的思想解决算法题&#xff0c;我从力扣上筛选了三道题&#xff0c;难度由浅到深&#xff0c;会附上题目链接以及算法原理和解题代码&#xff0c;希望大家能坚持看完&#xff0c;绝对能有收获&#xff0c;大家有更好的思…

Flask学习(六):蓝图(Blueprint)

蓝图&#xff08;Blueprint&#xff09;&#xff1a;将各个业务进行区分&#xff0c;然后每一个业务单元可以独立维护&#xff0c;Blueprint可以单独具有自己的模板、静态文件或者其它的通用操作方法&#xff0c;它并不是必须要实现应用的视图和函数的。 Demo目录结构&#xf…

计算机专业学习单片机有什么意义吗?

玩单片机跟玩计算机区别还是很大的, 单片机有众多的种类,每一种又可能有很多个系列.可以说单片机就是为了专款专用而生的.这样来达到产品成本的降低,这就是现在身边的很多的电子产品价格一降再降的原因之一.在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一…