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

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

相关推荐
Lee川1 天前
优雅进化的JavaScript:从ES6+新特性看现代前端开发范式
javascript·面试
肆忆_1 天前
# 用 5 个问题学懂 C++ 虚函数(入门级)
c++
Lee川1 天前
从异步迷雾到优雅流程:JavaScript异步编程与内存管理的现代化之旅
javascript·面试
晴殇i1 天前
揭秘JavaScript中那些“不冒泡”的DOM事件
前端·javascript·面试
绝无仅有1 天前
Redis过期删除与内存淘汰策略详解
后端·面试·架构
绝无仅有1 天前
Redis大Key问题排查与解决方案全解析
后端·面试·架构
AAA梅狸猫1 天前
Looper.loop() 循环机制
面试
AAA梅狸猫1 天前
Handler基本概念
面试
不想写代码的星星1 天前
虚函数表:C++ 多态背后的那个男人
c++
Wect1 天前
浏览器缓存机制
前端·面试·浏览器