「这是我参与2022首次更文挑战的第26天,活动详情查看:2022首次更文挑战」。
题目
给你一个二叉搜索树的根节点 root
,返回 树中任意两不同节点值之间的最小差值 。
差值是一个正数,其数值等于两值之差的绝对值。
示例 1
输入:root = [4,2,6,1,3]
输出:1
示例 2
输入:root = [1,0,48,null,null,12,49]
输出:1
提示
- 树中节点的数目范围是
- 0 <= Node.val <= 105
题解
思路
看到二叉搜索树,应该能想到中序遍历。
遍历一个二叉树,会访问每一个节点,拿节点做一些事情。
而中序遍历,它对于每一个节点,都先访问处理它的左子树中的节点,再访问处理它本身,再访问处理它的右子树中的节点。
由于二叉搜索树的性质,中序遍历访问处理的节点值的大小是递增的。
题目要求任意两个节点的最小的差值,它肯定发生在递增排列后的相邻的节点值之间。
我们用一个变量,保存上一个访问处理的节点值,求出当前访问的节点值与它之差,挑战最小的纪录,更小就更新。
从定义理解中序遍历
中序遍历基于 DFS,要对每一个节点做一些事情,做同样的事情。
前、中、后序遍历的区别在于,拿节点做一些事情的先后顺序不同。
中序遍历是,对每一个节点,先对它的左子树中的节点执行这些事情,再对当前节点执行这些逻辑,然后对节点的右子树中的节点执行相同的逻辑。
在 DFS 时,有三个阶段会碰到一个节点:
- 递归它的左子树之前
- 递归完它的左子树之后,递归它的右子树之前
- 递归完它的左、右子树之后
我们选择在递归它的左子树之后,递归它的右子树之前这个阶段,去执行我们处理节点的逻辑,就是中序遍历。
代码
const getMinimumDifference = (root) => {
let diff = Number.MAX_SAFE_INTEGER;
let preVal;
const inOrder = (root) => {
if (root == null) {
return;
}
inOrder(root.left);
if (preVal !== undefined && root.val - preVal < diff) {
diff = root.val - preVal;
}
preVal = root.val;
inOrder(root.right);
};
inOrder(root);
return diff;
}
结语
业精于勤,荒于嬉;行成于思,毁于随。