内容:
- 二叉搜索树的最小绝对差(530)
- 二叉搜索树中的众数(501)
- 二叉树的最近公共祖先(236)
1. 二叉搜索树的最小绝对差
难度:🔥🔥🔥
建议:需要领悟一下二叉树遍历上双指针操作,优先掌握递归
1.1 思路分析
二叉搜索树是有序的,所以我们采用中序遍历。
在递归遍历的过程中使用两个指针来记录前后两个节点,用一个result
结果集来记录我们的最小绝对差,然后不断更新我们的pre
节点让它指向cur
节点的上一个节点。
1.2 代码实现
class Solution {
TreeNode pre;
int result = Integer.MAX_VALUE;
public int getMinimumDifference(TreeNode root) {
if (root == null) {
return 0;
}
getMethod(root);
return result;
}
public void getMethod(TreeNode root){
if (root == null) {
return;
}
//左
getMethod(root.left);
//中
if (pre != null) {
result = Math.min(result,root.val - pre.val);
}
pre = root;
//右
getMethod(root.right);
}
}
1.3 注意事项
1.4 收获总结
2. 二叉搜索树中的众数
难度:🔥🔥🔥
建议:和二叉搜索树的最小绝对差差不多双指针思路,不过这里涉及到一个很巧妙的代码技巧
2.1 思路分析
这道题我们用双指针只实现一次遍历即可求得二叉搜索树中的众数。
当我们的count == maxSize(最大频率)
时,我们将该结果的值加入到我们的结果集result
中。
但是:如果这个maxCount
此时还不是真正最大频率,我们所加入的值并不是我们要求的值。
所以下面要做如下操作:
频率count 大于maxCount
的时候,不仅要更新maxCount
,而且要清空结果集result
,因为结果集之前的元素都失效了。
然后我们使用中序遍历即可求出众数。
2.2 代码实现
class Solution {
TreeNode pre;
int count;//用于统计单个元素出现的频率
int maxCount;//用于记录整个二叉树中最大的频率
List<Integer> result;
public int[] findMode(TreeNode root) {
result = new ArrayList<>();
pre = null;
traversal(root);
return result.stream().mapToInt(x -> x).toArray();
}
//使用中序遍历与双指针处理
private void traversal(TreeNode cur){
if (cur == null) {
return;
}
//左
traversal(cur.left);
//中
if (pre == null) {
count = 1;
} else if (cur.val == pre.val) {
count++;
}else {//当前后两个不相同时,重新记录
count = 1;
}
pre = cur;//更新pre 为cur的前一个节点
if (count == maxCount) {
result.add(cur.val);
}
if (count > maxCount) {
maxCount = count;
result.clear();
result.add(cur.val);
}
//右
traversal(cur.right);
return;
}
}
2.3 注意事项
2.4 收获总结
3. 二叉树的最近公共祖先
难度:🔥🔥🔥🔥
建议:本题较难,先看视频讲解
3.1 思路分析
这题关键在于如何理解将节点向上返回的过程。并且本题可以采用任何遍历方式。
我们使用回溯就可以实现自底向上查找的过程。
3.2 代码实现
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
//使用后序遍历,遍历整棵树
if (root == null) {
return null;
}
//如果找到对应的节点,我们将其返回
if (root == p || root == q) {
return root;
}
//左
TreeNode left = lowestCommonAncestor(root.left,p,q);
//右
TreeNode right = lowestCommonAncestor(root.right,p,q);
//中
if (left == null && right == null) {//未找到节点p,q
return null;
} else if (left == null && right != null) {
return right;
} else if (left != null && right == null) {
return left;
}else {//找到两个节点
return root;
}
}
}