一、LeetCode530. 二叉搜索树的最小绝对差
题目链接:530. 二叉搜索树的最小绝对差
二叉搜索树中值与根节点最接近的是左子树的最大值与右子树的最小值。
所以我们只需要找到左子树的最大值、右子树的最小值,让他们分别与根节点的值计算绝对差,然后更新最小绝对值,再通过递归找到左右子树的最小绝对差,与当前节点的最小绝对差比较后更新,最后返回最小的那个绝对差就可以了。
代码如下:
class Solution {
private int minInt = 100000;//记录绝对值差的最小值
public TreeNode leftMax(TreeNode root) {//计算左子树的最大值
if(root == null) return null;
if(root.right != null) return leftMax(root.right);
else return root;
}
public TreeNode rightMin(TreeNode root) {//计算右子树的最小值
if(root == null) return null;
if(root.left != null) return rightMin(root.left);
else return root;
}
public int getMinimumDifference(TreeNode root) {
if(root == null) return minInt;
if(root.left == null && root.right == null) return minInt;
TreeNode left = null;
TreeNode right = null;
if(root.left != null) left = leftMax(root.left);//如果有左子树,记录左子树的最大节点
if(root.right != null) right = rightMin(root.right);//如果有右子树,记录右子树的最小节点
//记录当前节点,左子树的最大节点、右子树的最小节点三者之间的差值的绝对值
int a = 100000;
int b = 100000;
if(left != null) a = Math.abs(root.val - left.val);
if(right != null) b = Math.abs(root.val - right.val);
minInt = Math.min(minInt,Math.min(a,b));
//向左右子树递归,找到左右子树的最小绝对差
int leftMinValue = 100000;
int rightMinValue = 100000;
if(root.left != null) leftMinValue = getMinimumDifference(root.left);
if(root.right != null) rightMinValue = getMinimumDifference(root.right);
minInt = Math.min(minInt, Math.min(leftMinValue,rightMinValue));
return minInt;
}
}
二、LeetCode 501. 二叉搜索树中的众数
题目链接;501. 二叉搜索树中的众数
创建一张HashMap表来记录二叉搜索树中每个值的节点个数。
将二叉树中的众数放到集合数组当中。
再将集合数组中的众数放到普通数组返回。
代码如下:
class Solution {
Map<Integer,Integer>map = new HashMap<>();//用HashMap来记录每个值的节点个数
public void travel(TreeNode root) {
if(root == null) return;
map.put(root.val, map.getOrDefault(root.val, 0) + 1);
if(root.left != null) travel(root.left);
if(root.right != null) travel(root.right);
}
public int[] findMode(TreeNode root) {
travel(root);
ArrayList<Integer> list = new ArrayList<>();//用来记录众数
int maxCount = 0;
for(Map.Entry<Integer, Integer> entry : map.entrySet()) {//将众数放到数组list中
if(entry.getValue() > maxCount) {
maxCount = entry.getValue();
list.clear();
list.add(entry.getKey());
}else if(entry.getValue() == maxCount) {
list.add(entry.getKey());
}
}
int index = 0;
int[] num = new int[list.size()];
for(int i : list) {//将list中的众数放到num数组然后返回num
num[index++] = i;
}
return num;
}
}
三、LeetCode236. 二叉树的最近公共祖先
题目链接:236. 二叉树的最近公共祖先
写两个方法,分别找出当前树是否含有节点p和q。
如果当前节点的左右子树都不同时含有节点pq,说明当前节点是pq的最近公共祖先。
如果左子树同时含有节点pq,说明左子节点也是pq的公共祖先,向左子节点递归继续寻找pq最近公共祖先。
右子树同时含有节点pq时同理,右子节点是pq的公共祖先,向右子节点递归继续寻找pq的最近公共祖先。
代码如下:
class Solution {
public boolean Containp(TreeNode root, TreeNode p) {//子树当中是否有节点p
if(root == null) return false;
if(root == p) return true;
boolean left = false;
boolean right = false;
if(root.left != null) left = Containp(root.left, p);
if(root.right != null) right = Containp(root.right, p);
return left || right;
}
public boolean Containq(TreeNode root, TreeNode q) {//子树当中是否有节点q
if(root == null) return false;
if(root == q) return true;
boolean left = false;
boolean right = false;
if(root.left != null) left = Containq(root.left, q);
if(root.right != null) right = Containq(root.right, q);
return left || right;
}
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
boolean leftContain = false;//用来标记左子树中是否同时含有节点pq
boolean rightCotain = false;//标记右子树中是否同时含有节点pq
if(root.left != null) {
leftContain = Containp(root.left, p) && Containq(root.left, q);
}
if(root.right != null) {
rightCotain = Containp(root.right, p) && Containq(root.right, q);
}
if(!leftContain && !rightCotain) {//如果左右子树都不同时含有节点pq则当前节点就是pq的最近公共祖先
return root;
}else if(leftContain == true) {//如果左子树同时含有pq节点,向左子树递归寻找pq的最近公共祖先
return lowestCommonAncestor(root.left, p, q);
} else {//如果右子树同时含有pq节点,向右子树递归寻找pq的最近公共祖先
return lowestCommonAncestor(root.right, p, q);
}
}
}
总结
二叉树中,递归是用到的最多的方法。