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)原题链接

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

相关推荐
沐雪架构师12 分钟前
大模型Agent面试精选15题(第四辑)-Agent与RAG(检索增强生成)结合的高频面试题
面试·职场和发展
未若君雅裁15 分钟前
JVM面试篇总结
java·jvm·面试
kk哥889936 分钟前
C++ 对象 核心介绍
java·jvm·c++
helloworddm37 分钟前
WinUI3 主线程不要执行耗时操作的原因
c++
YoungHong199239 分钟前
面试经典150题[072]:从前序与中序遍历序列构造二叉树(LeetCode 105)
leetcode·面试·职场和发展
无能者狂怒1 小时前
YOLO C++ Onnx Opencv项目配置指南
c++·opencv·yolo
im_AMBER2 小时前
Leetcode 78 识别数组中的最大异常值 | 镜像对之间最小绝对距离
笔记·学习·算法·leetcode
集智飞行2 小时前
c++函数传参的几种推荐方式
开发语言·c++
LYFlied2 小时前
【每日算法】LeetCode 25. K 个一组翻转链表
算法·leetcode·链表
点云SLAM3 小时前
C++ Template(模板)解读和模板报错如何“逆向阅读”定位
c++·c++20·c++模版·c++高级应用·c++模版报错定位