题目
给你一棵所有节点为非负值的二叉搜索树,请你计算树中任意两节点的差的绝对值的最小值。
示例:
输入:
1
\
3
/
2
输出:
1
解释:
最小绝对差为 1,其中 2 和 1 的差的绝对值为 1(或者 2 和 3)。
提示:
树中至少有 2 个节点。
本题与 783 https://leetcode-cn.com/problems/minimum-distance-between-bst-nodes/ 相同
解题思路
方法一:中序遍历
思路与算法
考虑对升序数组 a 求任意两个元素之差的绝对值的最小值,答案一定为相邻两个元素之差的最小值,即
其中 n 为数组 a 的长度。其他任意间隔距离大于等于 2 的下标对 (i,j) 的元素之差一定大于下标对 (i,i+1) 的元素之差,故不需要再被考虑。
回到本题,本题要求二叉搜索树任意两节点差的绝对值的最小值,而我们知道二叉搜索树有个性质为二叉搜索树中序遍历得到的值序列是递增有序的,因此我们只要得到中序遍历后的值序列即能用上文提及的方法来解决。
朴素的方法是经过一次中序遍历将值保存在一个数组中再进行遍历求解,我们也可以在中序遍历的过程中用 pre 变量保存前驱节点的值,这样即能边遍历边更新答案,不再需要显式创建数组来保存,需要注意的是 pre 的初始值需要设置成任意负数标记开头,下文代码中设置为 −1。
二叉树的中序遍历有多种方式,包括递归、栈、Morris 遍历等,读者可选择自己最擅长的来实现。下文代码提供最普遍的递归方法来实现,其他遍历方法的介绍可以详细看「94. 二叉树的中序遍历」的题解,这里不再赘述。
C++
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 getMinimumDifference(TreeNode* root) {
int ans = INT_MAX, pre = -1;
dfs(root, pre, ans);
return ans;
}
};
Python
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def getMinimumDifference(self, root: TreeNode) -> int:
def dfs(root):
if not root:
return
dfs(root.left)
nums.append(root.val)
dfs(root.right)
nums = []
dfs(root)
res = float('inf')
for i in range(1, len(nums)):
res = min(res, nums[i]-nums[i-1])
return res
Python(空间优化)
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def getMinimumDifference(self, root: TreeNode) -> int:
def dfs(root):
# nonlocal声明的变量不是局部变量,也不是全局变量,而是外部嵌套函数内的变量
nonlocal res, pre
if not root:
return
dfs(root.left)
if pre != -1:
res = min(res, root.val-pre)
pre = root.val
dfs(root.right)
pre = -1
# float('inf')作为一个无限的上限值进行比较。这对于找到某个事物的最低值很有用。
res = float('inf')
dfs(root)
return res
复杂度分析
- 时间复杂度:O(n),其中 n 为二叉搜索树节点的个数。每个节点在中序遍历中都会被访问一次且只会被访问一次,因此总时间复杂度为 O(n)。
- 空间复杂度:O(n)。递归函数的空间复杂度取决于递归的栈深度,而栈深度在二叉搜索树为一条链的情况下会达到 O(n) 级别。