530.二叉搜索树的最小绝对差
题目链接:530.二叉搜索树的最小绝对差
文档讲解:代码随想录
状态:还可以
思路:使用中序遍历来遍历二叉搜索树。在中序遍历过程中,比较当前节点和前驱节点的值,更新最小差值。返回二叉搜索树中任意两个节点值的最小差值。
递归:
int min = Integer.MAX_VALUE;
// 前驱节点
TreeNode pre;
public int getMinimumDifference(TreeNode root) {
// 如果当前节点为空,返回0
if (root == null) {
return 0;
}
// 递归遍历左子树
getMinimumDifference(root.left);
// 如果前驱节点不为空,计算当前节点和前驱节点的值差
if (pre != null) {
int dif = root.val - pre.val;
// 更新最小差值
min = Math.min(min, dif);
}
// 更新前驱节点为当前节点
pre = root;
// 递归遍历右子树
getMinimumDifference(root.right);
// 返回最小差值
return min;
}
迭代:
public int bfs(TreeNode root) {
// 使用双端队列模拟栈
Deque<TreeNode> stack = new LinkedList<>();
// 初始化前驱节点值为最大整数
int pre = Integer.MAX_VALUE;
// 初始化最小差值为一个很大的数值
int min = Integer.MAX_VALUE;
// 如果根节点为空,返回0
if (root == null) {
return 0;
}
// 将根节点添加到栈中
stack.addLast(root);
// 当栈不为空时,继续遍历
while (!stack.isEmpty()) {
// 弹出栈顶元素
TreeNode node = stack.pollLast();
if (node != null) {
// 先处理右子树
if (node.right != null) {
stack.addLast(node.right);
}
// 中间节点处理两次,设置一个null标记
stack.addLast(node);
stack.addLast(null);
// 再处理左子树
if (node.left != null) {
stack.addLast(node.left);
}
} else {
// 第二次遇到中间节点,进行实际处理
node = stack.pollLast();
// 计算当前节点与前驱节点的差值,并更新最小差值
min = Math.min(Math.abs(node.val - pre), min);
// 更新前驱节点的值
pre = node.val;
}
}
// 返回最小差值
return min;
}
501.二叉搜索树中的众数
题目链接:501.二叉搜索树中的众数
文档讲解:代码随想录
状态:还行,能做出来,虽然不是最优解
思路:通过中序遍历二叉搜索树,在遍历过程中统计每个节点值的出现次数,并找到出现次数最多的节点值。
题解:
public class FindMode {
// 存储众数的列表
List<Integer> list = new LinkedList<>();
public int[] findMode(TreeNode root) {
// 调用 getCount 方法遍历二叉树并找到众数
getCount(root);
// 将 list 转换为数组
int[] res = new int[list.size()];
for (int i = 0; i < res.length; i++) {
res[i] = list.get(i);
}
return res;
}
// 前一个节点的值,初始值为最小整数
int preVal = Integer.MIN_VALUE;
// 当前值出现的次数
int count = 0;
// 最大出现次数
int max = Integer.MIN_VALUE;
public void getCount(TreeNode root) {
if (root == null) {
return;
}
// 递归遍历左子树
getCount(root.left);
// 如果当前节点值等于前一个节点值,增加计数
if (preVal == root.val) {
count += 1;
} else {
// 如果当前节点值不等于前一个节点值,重置计数
count = 1;
}
// 如果当前计数大于最大计数,清空列表并更新最大计数
if (count > max) {
list.clear();
max = count;
list.add(root.val);
} else if (count == max) {
// 如果当前计数等于最大计数,将当前值加入列表
list.add(root.val);
}
// 更新前一个节点值为当前节点值
preVal = root.val;
// 递归遍历右子树
getCount(root.right);
}
}
236. 二叉树的最近公共祖先
题目链接:236. 二叉树的最近公共祖先
文档讲解:代码随想录
状态:想到使用后序遍历,但是判断逻辑没想出来(只想到true或false判断是否包含p,q,没想到使用返回节点和null来代替)
思路:使用后序遍历可以先获取左右子树的信息,然后利用左右子树信息和p,q比较从而实现判断逻辑。
题解:
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
// 如果根节点为空或根节点是p或q之一,则直接返回根节点
if (root == null || root == p || root == q) {
return root;
}
// 在左子树中查找最近公共祖先
TreeNode left = lowestCommonAncestor(root.left, p, q);
// 在右子树中查找最近公共祖先
TreeNode right = lowestCommonAncestor(root.right, p, q);
// 如果p和q分别在当前根节点的左右子树中,则当前根节点是最近公共祖先
if (left != null && right != null) {
return root;
}
// 如果左子树中找到了p或q(即left不为空),返回left
if (left != null) {
return left;
}
// 如果右子树中找到了p或q(即right不为空),返回right
if (right != null) {
return right;
}
// 如果左右子树中都没有找到p或q,返回null
return null;
}