day19 236. 二叉树的最近公共祖先&&501. 二叉搜索树中的众数&&530. 二叉搜索树的最小绝对差
- 二叉树的最近公共祖先(LeetCode 236)
功能概述
在给定的二叉树中,找出两个指定节点 p 和 q 的最近公共祖先(LCA)。
实现思路
高效递归方法:
递归结束条件为当前节点 root 为空或者等于 p 或 q,此时直接返回 root。
分别递归遍历左子树和右子树,根据左右子树的返回结果判断 LCA 的位置。
低效路径查找方法:
先通过 finedPath 方法找出从根节点到节点 p 的路径,存储在 pathP 中。
从 pathP 的末尾开始向前遍历,对于每个节点,使用 fined 方法判断节点 q 是否在该节点的子树中,若存在则该节点为 LCA。
复杂度分析
高效递归方法:时间复杂度为 (O(n)),空间复杂度为 (O(h)),其中 (n) 是树中节点的数量,(h) 是树的高度。
低效路径查找方法:时间复杂度为 (O(n^2)),空间复杂度为 (O(n))。
//236. 二叉树的最近公共祖先
//效率高一点 7ms
/*public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null || 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;
}
}*/
//效率低一点 8ms
boolean flag = true;
List<TreeNode> path=new ArrayList<>();
List<TreeNode> pathP;
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null || p == null || q == null) return null;
finedPath(root,p);
for (int i = pathP.size() - 1; i >= 0; i--) {
TreeNode node = pathP.get(i);
if(fined(node,q)) return node;
}
return null;
}
private void finedPath(TreeNode root, TreeNode p) {
if (root == null) return;
path.add(root);
if (root.val == p.val) {
pathP=new ArrayList<>(path);
flag=false;
return;
}
if (flag) finedPath(root.left, p);
if (flag) finedPath(root.right, p);
path.remove(path.size()-1);
}
private boolean fined(TreeNode root, TreeNode p) {
if (root == null) return false;
if (root.val == p.val) {
return true;
}
return fined(root.left, p) || fined(root.right, p);
}
-
二叉搜索树中的众数(LeetCode 501)
功能概述
找出给定二叉搜索树(BST)中出现频率最高的元素(众数)。
实现思路
中序遍历方法:
利用 BST 中序遍历结果为有序序列的特性,通过一次中序遍历统计每个元素的出现频率。
使用 count 记录当前元素的出现次数,maxCount 记录最大出现次数,resList 存储众数。
暴力算法:
先通过深度优先搜索(DFS)遍历树,使用 Map 统计每个元素的出现次数。
找出最大出现次数,然后遍历 Map 找出所有众数。
复杂度分析
中序遍历方法:时间复杂度为 (O(n)),空间复杂度为 (O(h)),其中 (n) 是树中节点的数量,(h) 是树的高度。
暴力算法:时间复杂度为 (O(n)),空间复杂度为 (O(n))。
//501. 二叉搜索树中的众数
//中序遍历
ArrayListresList;
int maxCount;
int count;
TreeNode pre;
public int[] findMode(TreeNode root) {
resList = new ArrayList<>();
maxCount = 0;
count = 0;
pre = null;
findMode1(root);
int[] res = new int[resList.size()];
for (int i = 0; i < resList.size(); i++) {
res[i] = resList.get(i);
}
return res;
}public void findMode1(TreeNode root) {
if (root == null) {
return;
}
//先处理左子树
findMode1(root.left);
//处理方式
int rootValue = root.val;
// 计数
if (pre == null || rootValue != pre.val) {
count = 1;
} else {
count++;
}
// 更新结果以及maxCount
if (count > maxCount) {
resList.clear();
resList.add(rootValue);
maxCount = count;
} else if (count == maxCount) {
resList.add(rootValue);
}
pre = root;
//最后处理右子树
findMode1(root.right);
}
//暴力算法 8ms
/public int[] findMode(TreeNode root) {
Map<Integer, Integer> map = new HashMap<>();
Listlist = new ArrayList<>(); /
dfsFindMode(root,map);
int max = Integer.MIN_VALUE;
for (Map.Entry<Integer, Integer> e : map.entrySet()) {
if (e.getValue() > max) {
max = e.getValue();
}
}
for (Map.Entry<Integer, Integer> e : map.entrySet()) {
if (e.getValue() == max) {
list.add(e.getKey());
}
}
return list.stream().mapToInt(i -> i).toArray();
}
private void dfsFindMode(TreeNode root,Map<Integer, Integer> map) {
if (root == null) return;
map.put(root.val, map.getOrDefault(root.val, 0) + 1);
dfsFindMode(root.left, map);
dfsFindMode(root.right, map);
} -
二叉搜索树的最小绝对差(LeetCode 530)
功能概述
计算给定二叉搜索树中任意两个节点之间的最小绝对差值。
实现思路
对于每个节点 root,分别找到其左子树中的最大值节点 cur1 和右子树中的最小值节点 cur2。
计算 cur1 与 root、cur2 与 root 的绝对差值,更新最小绝对差值 res。
递归遍历左子树和右子树。
复杂度分析
时间复杂度为 (O(n^2)),空间复杂度为 (O(h)),其中 (n) 是树中节点的数量,(h) 是树的高度。
//530. 二叉搜索树的最小绝对差
private int res=Integer.MAX_VALUE;
public int getMinimumDifference(TreeNode root) {
if (root == null) return -1;
dfsGetMinimumDifference(root);
return res;
}
private void dfsGetMinimumDifference(TreeNode root) {
TreeNode cur1 = root.left;
if (cur1!=null) {
while (cur1.right!=null) cur1 = cur1.right;
if (Math.abs(cur1.val-root.val)<res) res=Math.abs(cur1.val-root.val);
dfsGetMinimumDifference(root.left);
}
TreeNode cur2 = root.right;
if (cur2!=null) {
while (cur2.left!=null) cur2 = cur2.left;
if (Math.abs(cur2.val-root.val)<res) res=Math.abs(cur2.val-root.val);
dfsGetMinimumDifference(root.right);
}
}

浙公网安备 33010602011771号