目录
题目链接:530. 二叉搜索树的最小绝对差 - 力扣(LeetCode)
题目链接:501. 二叉搜索树中的众数 - 力扣(LeetCode)
题目链接:236. 二叉树的最近公共祖先 - 力扣(LeetCode)
“今年的我们已与去年不同,我们的爱人亦是如此。如果变换中的我们依旧爱着那个变化中的人,这可真是个令人欣喜的意外。”
题目链接:530. 二叉搜索树的最小绝对差 - 力扣(LeetCode)
思路:要找到二叉搜索树(BST)中任意两不同节点值之间的最小差值,利用BST的中序遍历特性:
在中序遍历中,节点值是按升序排列的,因此相邻节点的差值就是最小的。我们可以通过一次中序遍历,记录相邻节点的差值,并找出最小的差值。
class Solution530 {
private Integer prev; // 记录在中序遍历过程中前一个访问的节点值
private int minDiff; // 记录当前找到的最小差值
public int getMinimumDifference(TreeNode root) {
prev = null;
minDiff = Integer.MAX_VALUE;
inOrderTraversal(root);
return minDiff;
}
// 中序遍历BST,并计算最小差值
private void inOrderTraversal(TreeNode node) {
if (node == null) {
return;
}
// 递归遍历左子树
inOrderTraversal(node.left);
// 处理当前节点
if (prev != null){
minDiff = Math.min(minDiff, node.val - prev);
}
prev = node.val;
// 递归遍历右子树
inOrderTraversal(node.right);
}
}
题目链接:501. 二叉搜索树中的众数 - 力扣(LeetCode)
既然是搜索树,它中序遍历就是有序的。通过中序遍历,我们可以逐个访问节点值,并统计每个值的出现次数,从而找出众数。
- 使用中序遍历遍历BST。
- 在inOrderTraversal遍历过程中统计每个值的出现次数。使用双指针思路:
prev
记录前一个访问的节点值,count
记录当前节点值的出现次数,maxCount
记录最高的出现次数,result
存储所有出现次数等于最高次数的节点值。 - 记录最高的出现次数,并在遍历结束后找出所有出现次数等于最高次数的值。
class Solution501 {
private Integer prev = null;
private int count = 0;
private int maxCount = 0;
private List<Integer> result = new ArrayList<>();
public int[] findMode(TreeNode root) {
inOrderTraversal(root);
// 将结果列表转换为数组返回
int[] modes = new int[result.size()];
for (int i = 0; i < result.size(); i++) {
modes[i] = result.get(i);
}
return modes;
}
// 中序遍历BST
private void inOrderTraversal(TreeNode node) {
if (node == null) {
return;
}
// 递归遍历左子树
inOrderTraversal(node.left);
// 处理当前节点
if (prev == null || node.val != prev) {
count = 1;
} else {
count++;
}
if (count > maxCount) {
maxCount = count;
result.clear();
result.add(node.val);
} else if (count == maxCount) {
result.add(node.val);
}
prev = node.val;
// 递归遍历右子树
inOrderTraversal(node.right);
}
}
题目链接:236. 二叉树的最近公共祖先 - 力扣(LeetCode)
思路:在二叉树中找到两个指定节点的最近公共祖先(LCA,Lowest Common Ancestor)问题可以使用递归来解决。公共祖先的定义是:对于树中的两个节点 𝑝和 𝑞,最近公共祖先 𝐿𝐶𝐴是这两个节点的祖先节点且深度最大。
解题思路
- 递归定义:如果当前节点是 𝑝或 𝑞,或者当前节点的子树中包含 𝑝 和 𝑞,那么这个节点就是 𝑝 和 𝑞 的最近公共祖先。
- 递归函数:对每个节点,检查其左子树和右子树是否包含 𝑝 或 𝑞:
- 如果左子树和右子树各包含一个目标节点,则当前节点是 LCA。
- 如果两个目标节点都在左子树,递归在左子树中查找。
- 如果两个目标节点都在右子树,递归在右子树中查找。
- 返回值:如果找到 𝑝 或 𝑞,则返回该节点;两边都没有找到,则返回
null
。
class Solution236 {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
// 如果当前节点为空,返回 null
if (root == null) {
return null;
}
// 如果当前节点是 p 或 q,返回当前节点
if (root == p || root == q) {
return root;
}
// 递归搜索左子树和右子树
TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);
// 如果在左子树和右子树都找到了 p 或 q,那么当前节点就是最近公共祖先
if (left != null && right != null) {
return root;
}
// 如果在左子树和右子树只有一边找到了 p 或 q,返回找到的那个节点
return left != null ? left : right;
}
}