今日收获:二叉搜索树的最小绝对差,众数,最近公共祖先
1. 二叉搜索树的最小绝对差
题目链接:530. - 力扣(LeetCode)
思路:
1. 中序遍历二叉搜索树生成有序列表,再求最小差值。
2. 和判断二叉搜索树的思路相同,定义一个全局指针记录当前节点的上一个节点
方法:
class Solution {
TreeNode pre;
int result=Integer.MAX_VALUE;
public int getMinimumDifference(TreeNode root) {
min(root);
return result;
}
public void min(TreeNode node){
if (node==null){
return;
}
min(node.left); // 左
// 中节点
if (pre!=null&&Math.abs(node.val-pre.val)<result){
result=Math.abs(node.val-pre.val);
}
pre=node;
min(node.right);
}
}
总结:
1. 二叉搜索树是有序的,可以将其当作一个有序数组来求最值/差值
2. 记住在二叉搜索树中记录前后两个指针的方法
2. 二叉搜索树的众数
题目链接:501. - 力扣(LeetCode)
思路:
1. 如果是普通树,遍历树并把所有的值和频率存储在map集合中,再排序
2. 如果是二叉搜索树,中序遍历将值存储在列表中再处理
3. 递归法:定义一个全局指针记录当前节点的上一个节点。遍历到当前节点时,根据条件对频率计数,然后判断是否更新结果和频率最大值
方法:
class Solution {
TreeNode pre;
List<Integer> collection=new ArrayList<>();
int count=0;
int maxCount=0;
public int[] findMode(TreeNode root) {
find(root);
int len=collection.size();
int[] result=new int[len];
for (int i=0;i<len;i++){
result[i]=collection.get(i);
}
return result;
}
public void find(TreeNode node){
if (node==null){
return;
}
// 左
find(node.left);
// 计数
if (pre==null || node.val!=pre.val){
count=1;
}else if (node.val==pre.val){
count++;
}
// 更改结果和maxCount
if (count==maxCount){
collection.add(node.val);
}else if (count>maxCount){
maxCount=count;
collection.clear();
collection.add(node.val);
}
pre=node;
// 右
find(node.right);
}
}
总结:如果求最大值不止一个,首先设定一个最大值和结果集,遇到了相同值就加入结果集;如果遇到了更大的树就更新最大值,将结果集清空并加入当前的值。有点像打擂台。
3. 二叉树的最近公共祖先-后序遍历
题目链接:236. - 力扣(LeetCode)
思路:如果当前节点是祖先就返回当前节点;左右节点递归判断是否为空,不为空就返回,如果两个都不为空则返回当前节点
方法:
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
// 判断当前节点
if (root==p||root==q||root==null){
return root;
}
TreeNode left=lowestCommonAncestor(root.left,p,q);
TreeNode right=lowestCommonAncestor(root.right,p,q);
// 判断左右节点
if (left==null){
return right;
}
if (right==null){
return left;
}
if (left!=null&&right!=null){
return root;
}
return null;
}
}