LeetCode 面试经典 150_二叉搜索树_二叉搜索树的最小绝对差(85_530_C++_简单)

LeetCode 面试经典 150_二叉搜索树_二叉搜索树的最小绝对差(85_530_C++_简单)

题目描述:

给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值 。

差值是一个正数,其数值等于两值之差的绝对值。

输入输出样例:

示例 1:

输入 :root = [4,2,6,1,3]
输出:1

示例 2:

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

提示:

树中节点的数目范围是 [2, 104]

0 <= Node.val <= 105

题解:

解题思路:

思路一(中序遍历+数组):

1、二叉搜索树 所以其中序遍历有序 序列。可以采用中序遍历将数据存储在数组 中,再求相邻结点的差。两结点的最小的差只能是中序遍历的相邻结点。

2、复杂度分析:

① 时间复杂度:O(n),中序遍历二叉树的每个结点O(n),遍历一遍n个元素的数组O(n)。

② 空间复杂度:O(n),递归的中序遍历二叉树为O(log n),使用数组来存储每个结点的值O(n)。

思路二(中序遍历:DFS):

1、只使用递归,不使用额外的数组。

2、复杂度分析

① 时间复杂度:O(n),结点的个数。

② 空间复杂度:O(log n),递归的深度。

代码实现

代码实现(思路一(中序遍历+数组)):
cpp 复制代码
class Solution1 {
private:
    vector<int> inorderNums; // 用于存储二叉树的中序遍历结果

    // 中序遍历二叉树并将节点值存入inorderNums中
    void inorder(TreeNode *root) {
        if (root == nullptr) return; // 如果当前节点为空,返回
        inorder(root->left); // 递归遍历左子树
        inorderNums.push_back(root->val); // 将当前节点的值加入中序遍历结果中
        inorder(root->right); // 递归遍历右子树
    }

public:
    // 获取二叉树中任意两个节点值的最小绝对差
    int getMinimumDifference(TreeNode* root) {
        inorder(root); // 通过中序遍历填充inorderNums

        int ans = INT_MAX; // 初始化答案为一个最大值,后续会通过min函数更新
        for (int i = 1; i < inorderNums.size(); i++) {
            // 计算相邻两个节点之间的差,并更新答案为最小差值
            ans = min(inorderNums[i] - inorderNums[i - 1], ans);
        }
        
        return ans; // 返回最小的差值
    }
};
代码实现(思路二(中序遍历:DFS)):
cpp 复制代码
class Solution2 {
private:
    // 中序遍历二叉树并计算相邻节点值的最小绝对差
    void inorder(TreeNode *root, int &pre, int &ans) {
        if (root == nullptr) return; // 如果当前节点为空,返回

        inorder(root->left, pre, ans); // 递归遍历左子树
        
        // 处理当前节点的值
        if (pre == -1) {
            // 这是树中的第一个节点,记录该节点值
            pre = root->val;
        } else {
            // 计算当前节点与前一个节点的绝对差,并更新最小差值
            ans = min(root->val - pre, ans);
            // 更新前一个节点的值为当前节点的值
            pre = root->val;
        }
        
        inorder(root->right, pre, ans); // 递归遍历右子树
    }

public:
    // 获取二叉树中任意两个节点值的最小绝对差
    int getMinimumDifference(TreeNode* root) {
        int pre = -1; // pre用于记录前一个节点的值,初始设为-1
        int ans = INT_MAX; // 初始化最小差值为最大整数,表示初始时无差值
        inorder(root, pre, ans); // 通过中序遍历计算最小差值
        return ans; // 返回最小的绝对差值
    }
};
以思路二为例进行调试
cpp 复制代码
#include<iostream>
#include<vector>
#include<queue>
using namespace std;

struct TreeNode
{
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode():val(0),left(nullptr),right(nullptr){}
    TreeNode(int x):val(x),left(nullptr),right(nullptr){}
    TreeNode(int x,TreeNode *left,TreeNode *right):val(x),left(left),right(right){}
};


//建立二叉树,注意数组中-1为null
TreeNode *createTree(vector<int> &nums){
    if (nums.empty()) return nullptr;
    queue<TreeNode *> Q;
    TreeNode *root=new TreeNode(nums[0]);
    Q.push(root);
    int i=1;
    while (i<nums.size()){
        TreeNode *node=Q.front();
        Q.pop();
        if (i<nums.size() && nums[i]!=-1){
            node->left=new TreeNode(nums[i]);
            Q.push(node->left);
        } 
        i++;

        if (i<nums.size() && nums[i]!=-1){
            node->right=new TreeNode(nums[i]);
            Q.push(node->right);
        } 
        i++;
        
    }
    return root;
}

//中序遍历验证二叉树是否创建成功
// void inorder(TreeNode *root){
//     if(root==nullptr) return;
//     inorder(root->left);
//     cout<<root->val<<" ";
//     inorder(root->right);
// }

//方法二:只使用递归,不使用额外的数组
//时间复杂度是O(n),结点的个数
//空间复杂度是O(log n),递归的深度
class Solution2 {
private:
    // 中序遍历二叉树并计算相邻节点值的最小绝对差
    void inorder(TreeNode *root, int &pre, int &ans) {
        if (root == nullptr) return; // 如果当前节点为空,返回

        inorder(root->left, pre, ans); // 递归遍历左子树
        
        // 处理当前节点的值
        if (pre == -1) {
            // 这是树中的第一个节点,记录该节点值
            pre = root->val;
        } else {
            // 计算当前节点与前一个节点的绝对差,并更新最小差值
            ans = min(root->val - pre, ans);
            // 更新前一个节点的值为当前节点的值
            pre = root->val;
        }
        
        inorder(root->right, pre, ans); // 递归遍历右子树
    }

public:
    // 获取二叉树中任意两个节点值的最小绝对差
    int getMinimumDifference(TreeNode* root) {
        int pre = -1; // pre用于记录前一个节点的值,初始设为-1
        int ans = INT_MAX; // 初始化最小差值为最大整数,表示初始时无差值
        inorder(root, pre, ans); // 通过中序遍历计算最小差值
        return ans; // 返回最小的绝对差值
    }
};

int main(int argc, char const *argv[])
{
    vector<int> nums={4,2,6,1,3};
    TreeNode* root= createTree(nums);
    //验证二叉树是否创建成功
    //inorder(root);

    Solution2 s2;
    cout<<s2.getMinimumDifference(root)<<endl;

    return 0;
}

LeetCode 面试经典 150_二叉搜索树_二叉搜索树的最小绝对差(85_530)原题链接

欢迎大家和我沟通交流(✿◠‿◠)

相关推荐
handler0113 小时前
Linux 内核剖析:进程优先级、上下文切换与 O(1) 调度算法
linux·运维·c语言·开发语言·c++·笔记·算法
zhouwy11313 小时前
Linux进程与线程编程详解
linux·c++
leoufung14 小时前
LeetCode 76:Minimum Window Substring 题解与滑动窗口思维详解
算法·leetcode·职场和发展
A7bert77714 小时前
【YOLOv8pose部署至RDK X5】模型训练→转换bin→Sunrise 5部署
c++·python·深度学习·yolo·目标检测
li16709027014 小时前
第二十七章:智能指针
c语言·数据结构·c++·visual studio
风筝在晴天搁浅15 小时前
LeetCode 92.反转链表Ⅱ
算法·leetcode·链表
weisian15115 小时前
基础篇--概念原理-2-参数是什么?——从原理到实战,一篇讲透
面试·职场和发展·模型参数·7b和70b·参数=规则,不是原始数据
王老师青少年编程15 小时前
csp信奥赛C++高频考点专项训练之贪心算法 --【贪心与二分判定】:数列分段 Section II
c++·算法·贪心·csp·信奥赛·二分判定·数列分段 section ii
zh_xuan15 小时前
libcurl调用https接口
c++·libcurl
就叫飞六吧15 小时前
QT写一个桌面程序exe并动态打包基本流程(c++)
开发语言·c++