算法练习-二叉搜索树的最小绝对差(思路+流程图+代码)

难度参考

        难度:中等

        分类:二叉树

        难度与分类由我所参与的培训课程提供,但需要注意的是,难度与分类仅供参考。且所在课程未提供测试平台,故实现代码主要为自行测试的那种,以下内容均为个人笔记,旨在督促自己认真学习。

题目

        给你一个二叉搜索树的根节点root,返回树中任意两不同节点值之间的最小差值。差值是一个正数,其数值等于两值之差的绝对值。
        示例1:
        输入:root=[4,2,6,1,3]
        输出:1

        示例2:
        输入:root=[1,0,48,null,null,12,49]
        输出:1

        提示:
        树中节点的数目范围是 [2,10(4)]
        0<=Node.Va1<=10(5)

思路

        要在二叉搜索树中找到任意两个节点差值的最小值,我们可以利用二叉搜索树的性质,即中序遍历得到的值是递增的。在中序遍历过程中,我们只需保持跟踪前一个节点的值,并与当前节点的值求差的绝对值,进而不断更新最小差值即可。

        具体步骤:

  1. 初始化一个变量minDiff作为最小差值,并将其设置为一个非常大的数(例如INT_MAX)。
  2. 初始化一个变量prev用于存储上一个访问过的节点,开始时为nullptr
  3. 对树进行中序遍历,按照左节点、根节点、右节点的顺序。
  4. 在访问每个节点时,如果前一节点prev不是nullptr(也就是说这不是访问的第一个节点),那么计算当前节点和前一节点的差值的绝对值,更新minDiff为当前差值与minDiff之中的较小值。
  5. 将当前节点设置为新的prev,然后继续遍历。
  6. 中序遍历完成后,minDiff中存储的就是任意两个节点差值的最小值。

示例

        二叉搜索树(Binary Search Tree),也称为二叉排序树或二叉查找树,它是一种特殊的二叉树,具有以下性质:

  • 如果二叉搜索树不是空树,则它的左子树中的所有结点的值都小于它的根结点的值。
  • 如果二叉搜索树不是空树,则它的右子树中的所有结点的值都大于它的根结点的值。
  • 每一层(除了最底层)的结点数量不超过最大结点数的半数。

        此外,二叉搜索树的左子树和右子树自身也是二叉搜索树。这种结构使得二叉搜索树非常适合用于快速检索,即二分搜索算法。

        假设我们有如下这棵二叉搜索树(BST):

     4
   /   \
  2     6
 / \
1   3

        我们要找到BST中任意两个不同节点之间的最小差值。

  1. 对树执行中序遍历(左->右->根),访问顺序将会是 1 -> 2 -> 3 -> 4 -> 6,因为二叉搜索树中序遍历的结果是升序排列的。

  2. 开始时,minDiff初始化为INT_MAX(一个非常大的数),prevNode初始化为nullptr

  3. 访问节点 1:

    • prevNodenullptr,所以我们不更新minDiff
    • prevNode设置为指向当前节点(值为 1 的节点)。
  4. 访问节点 2:

    • 现在prevNode不是nullptr,计算差值abs(2 - 1)得到 1。
    • 更新minDiffmin(INT_MAX, 1),因此minDiff现在是 1。
    • 更新prevNode为当前节点(值为 2 的节点)。
  5. 访问节点 3:

    • 计算差值abs(3 - 2)得到 1。
    • 更新minDiffmin(1, 1),因此minDiff保持为 1。
    • 更新prevNode为当前节点(值为 3 的节点)。
  6. 访问节点 4:

    • 计算差值abs(4 - 3)得到 1。
    • 更新minDiffmin(1, 1),因此minDiff保持为 1。
    • 更新prevNode为当前节点(值为 4 的节点)。
  7. 访问节点 6:

    • 计算差值abs(6 - 4)得到 2。
    • 更新minDiffmin(1, 2),因此minDiff保持为 1。
    • 更新prevNode为当前节点(值为 6 的节点)。
  8. 中序遍历完成,所有节点都已经访问过,minDiff现在存储的是任意两个节点的最小差值,这个例子中为 1。

梳理

        在二叉搜索树(Binary Search Tree,BST)中,中序遍历可以按照顺序访问节点。所以,通过对BST执行中序遍历,我们可以得到一个升序排列的节点序列。

        利用中序遍历,我们可以通过在遍历的过程中计算相邻节点之间的差值来减少比较的次数。

        具体来说,我们用两个变量来追踪状态:

  • prevNode:指向前一个访问的节点。
  • minDiff:存储当前找到的最小差值。

        在遍历过程中,我们比较当前节点与前一个节点之间的差值,并将其与之前找到的最小差值进行比较和更新。

        由于中序遍历的性质,对于相邻的节点,它们之间的差值将是最小的。所以我们只需要在遍历过程中比较相邻节点的差值,并将其与当前的最小差值进行比较和更新。

        通过这种方法,我们可以在遍历完整个BST之后找到任意两个不同节点之间的最小差值,而不需要比较所有可能的差值。

代码

#include <iostream>  // 包含输入输出流的库
#include <cmath>  // 包含数学库
#include <climits>  // 包含整数类型的极限值宏

using namespace std;  // 使用std命名空间

struct TreeNode {  // 定义结构体TreeNode
    int val;  // 节点值
    TreeNode *left;  // 左子节点指针
    TreeNode *right;  // 右子节点指针
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}  // 构造函数
};

int minDiff = INT_MAX;  // 定义全局变量 minDiff,初始化为整数类型的最大值
TreeNode* prevNode = nullptr;  // 定义全局变量 prevNode,初始化为nullptr

void inorder(TreeNode* node) {  // 定义中序遍历函数 inorder
    if (!node) return;  // 如果节点为空,返回
    
    inorder(node->left);  // 递归调用:遍历左子树

    if (prevNode) {  // 如果 prevNode 不为空
        minDiff = min(minDiff, abs(node->val - prevNode->val));  // 计算当前节点值与前一个节点值的差的绝对值,并与 minDiff 进行比较和更新
    }
    prevNode = node;  // 更新 prevNode 为当前节点

    inorder(node->right);  // 递归调用:遍历右子树
}

int getMinimumDifference(TreeNode* root) {  // 定义函数 getMinimumDifference,参数为根节点
    inorder(root); // 进行中序遍历更新最小差值 minDiff
    return minDiff;  // 返回最小差值
}

// 主函数
int main(){
    TreeNode *root1 = new TreeNode(4);  // 创建二叉树,根节点值为4
    root1->left = new TreeNode(2);  // 设置左子节点的值为2
    root1->right = new TreeNode(6);  // 设置右子节点的值为6
    root1->left->left = new TreeNode(1);  // 设置左子节点的左子节点的值为1
    root1->left->right = new TreeNode(3);  // 设置左子节点的右子节点的值为3

    cout << "示例1: " << getMinimumDifference(root1) << endl; // 应该输出 1
    
    // 清理内存
    delete root1->left->left;
    delete root1->left->right;
    delete root1->left;
    delete root1->right;
    delete root1;
    minDiff = INT_MAX;  // 重置 minDiff 和 prevNode 以进行下一个测试
    prevNode = nullptr;

    TreeNode *root2 = new TreeNode(1);  // 创建二叉树,根节点值为1
    root2->left = new TreeNode(0);  // 设置左子节点的值为0
    root2->right = new TreeNode(48);  // 设置右子节点的值为48
    root2->right->left = new TreeNode(12);  // 设置右子节点的左子节点的值为12
    root2->right->right = new TreeNode(49);  // 设置右子节点的右子节点的值为49
    
    cout << "示例2: " << getMinimumDifference(root2) << endl; // 应该输出 1

    // 清理内存
    delete root2->left;
    delete root2->right->left;
    delete root2->right->right;
    delete root2->right;
    delete root2;
    
    return 0;  // 返回0表示成功
}

        时间复杂度:O(n)

        空间复杂度:O(n)

打卡

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

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

相关文章

代码随想录 Leetcode37. 解数独

题目&#xff1a; 代码(首刷看解析 2024年2月6日&#xff09;&#xff1a; class Solution { private:bool backtracking(vector<vector<char>>& board) {for (int i 0; i < 9; i) {for (int j 0; j < 9; j) {if (board[i][j] .) {for (char k 1; k…

“掌握温度,感知湿度,一触即知!”DHT11温湿度传感器,为您的生活增添一份关怀与精准。#非标协议【下】

“掌握温度&#xff0c;感知湿度&#xff0c;一触即知&#xff01;”DHT11温湿度传感器&#xff0c;为您的生活增添一份关怀与精准。#非标协议【下】 前言预备知识1.DHT11温湿度传感器初识1.1产品概述1.2与51单片机接线1.3数据传送逻辑和数据格式 2.发送时序检测DHT11温湿度传感…

Linux基础-磁盘

1.磁盘分区 1.分区有固定大小 2.直接写在这块盘的磁盘分区表中&#xff08;DPT&#xff09;&#xff0c;和上面装什么操作系统没有任何关系 2.每一个磁盘分区都要先有一个磁盘分区类型 GPT&#xff08;首选&#xff09; MBR 3.磁盘专业术语叫做块设备&#xff08;Block Dev…

numpy基础之切片索引

1 numpy基础之切片索引 多维数组有多个轴&#xff0c;索引下标从0轴开始&#xff0c;每个轴下标用逗号分隔。 比如[m,n,o]&#xff0c;表示0轴上索引为m&#xff0c;1轴上索引为n&#xff0c;2轴上索引为o的下标。 切片索引下标是在指定轴上用冒号选取一定范围的下标。 比如…

mac缩小图片大小的软件有哪些?推荐6款实用软件

mac缩小图片大小的软件有哪些&#xff1f;在处理图片时&#xff0c;我们经常需要调整图片的大小以适应不同的需求。在Mac上&#xff0c;有许多软件可以帮助我们实现这一目标。本文将介绍6款知名的图片缩小软件&#xff0c;让你轻松应对图片大小的调整。 1.改图鸭 这是一款功能…

亿级流量高并发春晚互动前端技术揭秘

前言 2022年1月&#xff0c;京东成为央视总台2022年春节联欢晚会独家互动合作伙伴&#xff0c;双方在红包互动、电商等方面展开全方位深度合作。在除夕当天产生691亿次互动&#xff0c;送出15亿元红包好物。 如何在这种大规模、高并发的场景下&#xff0c;确保系统的稳定性和…

这是一篇学习记录(二) —— RPA应用

RPA可以做数据提取、表单填写和文件移动。RPA 可以在不相关的软件系统中自动执行各种活动和事务&#xff0c;从而释放人力资源&#xff0c;使其优先处理更复杂的任务。 以下是 RPA 在不同领域的典型应用&#xff1a; 金融和银行业&#xff1a;RPA 在金融和会计领域有广泛应用…

Linux实验记录:使用Postfix与Dovecot部署邮件系统

前言&#xff1a; 本文是一篇关于Linux系统初学者的实验记录。 参考书籍&#xff1a;《Linux就该这么学》 实验环境&#xff1a; VmwareWorkStation 17——虚拟机软件 RedHatEnterpriseLinux[RHEL]8——红帽操作系统 备注&#xff1a; Web服务和FTP文件传输服务虽能实现文…

Stable Diffusion 模型下载:majicMIX reverie 麦橘梦幻

文章目录 模型介绍生成案例案例一案例二案例三案例四案例五案例六案例七案例八案例九案例十 下载地址 模型介绍 非常推荐的一个梦幻风格的大模型&#xff0c;由国人“Merjic”发布&#xff0c;下载量颇高。基于majicMIX_lux合并了一个2.5D模型。它与majicMIX_fantasy有类似的方…

【开源】SpringBoot框架开发城市桥梁道路管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、系统展示四、核心代码4.1 查询城市桥梁4.2 新增城市桥梁4.3 编辑城市桥梁4.4 删除城市桥梁4.5 查询单个城市桥梁 五、免责说明 一、摘要 1.1 项目介绍 基于VueSpringBootMySQL的城市桥梁道路管理系统&#xff0c;支持…

01-Datahub是什么?

Datahub是LinkedIn开源的基于现代数据栈的元数据管理平台&#xff0c;原来叫做WhereHows 。经过一段时间的发展datahub于2020年2月在Github开源。 官网地址为&#xff1a;A Metadata Platform for the Modern Data Stack | DataHub 源码地址为&#xff1a;GitHub - datahub-p…

Java实现视频抽帧

&#x1f913; 1️⃣配置Maven 在pox.xml中加入 <dependencies><dependency><groupId>org.bytedeco</groupId><artifactId>javacv-platform</artifactId><version>1.5.7</version></dependency> </dependencies…

代码随想录 Leetcode51. N 皇后

题目&#xff1a; 代码(首刷看解析 2024年2月6日&#xff09;&#xff1a; class Solution { private:vector<vector<string>> res;void backtracking(int n, int row, vector<string>& chessboard) {if (row n) {res.push_back(chessboard);return;}f…

论文阅读-面向公平性的分布式系统负载均衡机制

摘要 当一组自利的用户在分布式系统中共享多个资源时&#xff0c;我们面临资源分配问题&#xff0c;即所谓的负载均衡问题。特别地&#xff0c;负载均衡被定义为将负载分配到分布式系统的服务器上&#xff0c;以便最小化作业响应时间并提高服务器的利用率。在本文中&#xff0…

UE5 解析Base64加密的json并解决中文乱码

参考资料: IntelliJ IDEA 设置编码为utf-8编码_idea如何转化utf-8-CSDN博客 【UE4】FString TCHAR_TO_UTF8宏的一些坑-CSDN博客 这是最有用的Unreal Engine FString TArray<uint8> utf-8互转 - 知乎 FString UMyBlueprintFunctionLibrary::LoadStringBase64Decode(FSt…

Tiktok云手机是什么,做tiktok养号有什么优势?

随着抖音海外版的兴起&#xff0c;给跨境电商带来了前所未有的巨大商机&#xff0c;打算做Tiktok带货的跨境商家越来越多了。本文将介绍如何通过tiktok云手机轻松养号涨粉。 账号的安全稳定是做好tiktok的基础&#xff0c;早期大家用的比较多的是实体手机。但是这种方法有几个弊…

人工智能|深度学习——基于全局注意力的改进YOLOv7-AC的水下场景目标检测系统

代码下载&#xff1a; 基于全局注意力的改进YOLOv7-AC的水下场景目标检测系统.zip资源-CSDN文库 1.研究的背景 水下场景目标检测是水下机器人、水下无人机和水下监控等领域中的重要任务之一。然而&#xff0c;由于水下环境的复杂性和特殊性&#xff0c;水下目标检测面临着许多挑…

深度解析 Netty 架构与原理

一共 28661字&#xff0c;耐心看完。 在阅读本文前最好有 Java 的 IO 编程经验&#xff08;知道 Java 的各种 IO 流&#xff09;&#xff0c;以及 Java 网络编程经验&#xff08;用 ServerSocket 和 Socket 写过 demo&#xff09;&#xff0c;并对 Java NIO 有基本的认识&…

Etsy做什么店铺比较靠谱? 什么叫做真人店?

作为Etsy是美国最大的原创手工在线销售平台之一&#xff0c;以其店铺利润高、平台佣金低、平台同质化不严重的优点在跨境电商里颇具竞争力。然而Etsy开店却不是件容易事&#xff0c;原因是Etsy真人店对于环境以及卖家的运营操作要求较高&#xff0c;下面就给各位有意入局Etsy的…

计算机毕业设计 | SSM 旅游网站后台管理系统(附源码)

1&#xff0c;概述 1.1 背景分析 随着人们生活水平的提高和对休闲旅游的日益重视&#xff0c;旅游业已成为全球最大的经济产业之一。越来越多的人选择通过在线方式进行旅行预订&#xff0c;这种趋势为旅游网站提供了巨大的商机。用户体验是决定旅游网站成功与否的关键因素。良…