代码随想录算法训练营第二十一天|530.二叉搜索树的最小绝对差、501.二叉搜索树中的众数、236.二叉树的最近公共祖先
530.二叉搜索树的最小绝对差
给你一个二叉搜索树的根节点 root
,返回 树中任意两不同节点值之间的最小差值 。
差值是一个正数,其数值等于两值之差的绝对值。
示例 1:
输入:root = [4,2,6,1,3]
输出:1
题解:注意二叉搜索树是有序的!!!当中序遍历二叉树时,数组就是有序的。本题可以采用中序遍历加入数组中,然后遍历数组,记录最小的两个数据之和。
如果不单独定义数组的话,直接比较大小,要怎么记录当前节点的前一个节点呢?这个节点又怎么确保一直跟着遍历节点走呢?
代码:
class Solution {
TreeNode pre=null;
int res=Integer.MAX_VALUE;
public int getMinimumDifference(TreeNode root) {
zhongxv(root);
return res;
}
public void zhongxv(TreeNode node){
if(node==null) return;
zhongxv(node.left);
if(pre!=null){
res=Math.min(res,node.val-pre.val);
}
pre=node;
zhongxv(node.right);
}
}
501.二叉搜索树中的众数
给你一个含重复值的二叉搜索树(BST)的根节点 root
,找出并返回 BST 中的所有 众数(即,出现频率最高的元素)。
如果树中有不止一个众数,可以按 任意顺序 返回。
假定 BST 满足如下定义:
- 结点左子树中所含节点的值 小于等于 当前节点的值
- 结点右子树中所含节点的值 大于等于 当前节点的值
- 左子树和右子树都是二叉搜索树
示例 1:
输入:root = [1,null,2,2]
输出:[2]
题解:找到二叉搜索树中出现次数最多的数。可以中序遍历加入数组,然后遍历数组。也可以不用数组的方法。在遍历的时候记录最大值,然后加入数组,因为只遍历一次,所以在遍历的过程中需要更新最大值和结果数组的值。
代码:
class Solution {
List<Integer> res=new ArrayList<>();
TreeNode pre=null;
int maxCount=0;
int count=0;
public int[] findMode(TreeNode root) {
traversal(root);
int [] ans=new int[res.size()];
for(int i=0;i<ans.length;i++){
ans[i]=res.get(i);
}
return ans;
}
public void traversal(TreeNode node){
if(node==null) return;
traversal(node.left);
if(pre==null){
count=1;
}else if(pre.val==node.val){
count+=1;
}else{
count=1;
}
if(count==maxCount){
res.add(node.val);
}else if(count>maxCount){ //更新最大值和结果数组
maxCount=count;
res.clear();
res.add(node.val);
}
pre=node;
traversal(node.right);
}
}
236.二叉树的最近公共祖先
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
示例 1:
输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
输出:3
解释:节点 5 和节点 1 的最近公共祖先是节点 3 。
题解:需要用到回溯的话,遍历方式是后序遍历。因为中是处理逻辑和回溯节点。
代码:
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
return traversal(root,p,q);
}
//后序遍历
public TreeNode traversal(TreeNode node,TreeNode p,TreeNode q){
if(node==null) return null;
if(node==q || node==p) return node;
TreeNode left=traversal(node.left,p,q);
TreeNode right=traversal(node.right,p,q);
//中节点处理逻辑
if(left!=null && right!=null) return node; //左右节点都不为空,说明这个节点是祖先节点
if(left!=null && right==null) return left; //只有一边不为空,也要将这个节点返回去
if(left==null && right!=null) return right;
return null;
}
}