LeetCode每日签到题目(2021-04-13)《二叉搜索树节点最小距离》官方答案抄袭

题目描述:

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

示例1:

输入:root = [4,2,6,1,3]
输出:1
在这里插入图片描述


示例2:

输入:root = [1,0,48,null,null,12,49]
输出:1
在这里插入图片描述


提示:

  • 树中节点数目在范围 [2, 100] 内
  • 0 <= Node.val <= 105

官方题解:

思路与算法

考虑对升序数组 a a a 求任意两个元素之差的最小值,答案一定为相邻两个元素之差的最小值,即

a n s = min ⁡ i = 0 n − 2 { a [ i + 1 ] − a [ i ] } { ans }=\min _{i=0}^{n-2}\{a[i+1]-a[i]\} ans=mini=0n2{a[i+1]a[i]}

其中 n n n 为数组 a a a 的长度。其他任意间隔距离大于等于 2 2 2 的下标对 ( i , j ) (i,j) (i,j) 的元素之差一定大于下标对 ( i , i + 1 ) (i,i+1) (i,i+1) 的元素之差,故不需要再被考虑。

回到本题,本题要求二叉搜索树任意两节点差的最小值,而我们知道二叉搜索树有个性质为二叉搜索树中序遍历得到的值序列是递增有序的,因此我们只要得到中序遍历后的值序列即能用上文提及的方法来解决。

朴素的方法是经过一次中序遍历将值保存在一个数组中再进行遍历求解,我们也可以在中序遍历的过程中用 pre \textit{pre} pre 变量保存前驱节点的值,这样即能边遍历边更新答案,不再需要显式创建数组来保存,需要注意的是 pre \textit{pre} pre 的初始值需要设置成任意负数标记开头,下文代码中设置为 - 1 1 1

二叉树的中序遍历有多种方式,包括递归、栈、Morris 遍历等,读者可选择自己最擅长的来实现。下文代码提供最普遍的递归方法来实现,


代码

class Solution {
public:
    void dfs(TreeNode* root, int& pre, int& ans) {
        if (root == nullptr) {
            return;
        }
        dfs(root->left, pre, ans);
        if (pre == -1) {
            pre = root->val;
        } else {
            ans = min(ans, root->val - pre);
            pre = root->val;
        }
        dfs(root->right, pre, ans);
    }
    int minDiffInBST(TreeNode* root) {
        int ans = INT_MAX, pre = -1;
        dfs(root, pre, ans);
        return ans;
    }
};
class Solution {
    int pre;
    int ans;

    public int minDiffInBST(TreeNode root) {
        ans = Integer.MAX_VALUE;
        pre = -1;
        dfs(root);
        return ans;
    }

    public void dfs(TreeNode root) {
        if (root == null) {
            return;
        }
        dfs(root.left);
        if (pre == -1) {
            pre = root.val;
        } else {
            ans = Math.min(ans, root.val - pre);
            pre = root.val;
        }
        dfs(root.right);
    }
}
void dfs(struct TreeNode* root, int* pre, int* ans) {
    if (root == NULL) {
        return;
    }
    dfs(root->left, pre, ans);
    if (*pre == -1) {
        *pre = root->val;
    } else {
        *ans = fmin(*ans, root->val - (*pre));
        *pre = root->val;
    }
    dfs(root->right, pre, ans);
}

int minDiffInBST(struct TreeNode* root) {
    int ans = INT_MAX, pre = -1;
    dfs(root, &pre, &ans);
    return ans;
}

复杂度分析

  • 时间复杂度: O ( n ) O(n) O(n),其中 n n n 为二叉搜索树节点的个数。每个节点在中序遍历中都会被访问一次且只会被访问一次,因此总时间复杂度为 O ( n ) O(n) O(n)

  • 空间复杂度: O ( n ) O(n) O(n)。递归函数的空间复杂度取决于递归的栈深度,而栈深度在二叉搜索树为一条链的情况下会达到 O ( n ) O(n) O(n) 级别。

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/minimum-distance-between-bst-nodes/solution/er-cha-sou-suo-shu-jie-dian-zui-xiao-ju-8u87w/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值