This commit is contained in:
zhangsan 2025-06-03 14:51:50 +08:00
parent 5b858edaa8
commit 566e4136f5
4 changed files with 175 additions and 0 deletions

View File

@ -0,0 +1,79 @@
package tree;
import java.util.ArrayList;
import java.util.List;
/**
* 题目501. 二叉搜索树中的众数 (findMode)
* 描述给你一个含重复值的二叉搜索树BST的根节点 root 找出并返回 BST 中的所有 众数出现频率最高的元素
*
* 如果树中有不止一个众数可以按 任意顺序 返回
*
* 假定 BST 满足如下定义
*
* 结点左子树中所含节点的值 小于等于 当前节点的值
* 结点右子树中所含节点的值 大于等于 当前节点的值
* 左子树和右子树都是二叉搜索树
*
* 示例 1
输入root = [1,null,2,2]
输出[2]
* 链接https://leetcode.cn/problems/find-mode-in-binary-search-tree/
*/
public class FindMode {
private int maxCount = 0; // 当前已知的最大频率
private int count = 0; // 正在统计的当前节点值的出现次数
private TreeNode pre = null; // 中序遍历时前一个被访问的节点
private List<Integer> result = new ArrayList<>(); // 存放众数的列表
public int[] findMode(TreeNode root) {
// 初始化如果同一个 Solution 实例可能被重复调用需要做清空
maxCount = 0;
count = 0;
pre = null;
result.clear();
// 递归中序遍历
inorder(root);
// List<Integer> 转成 int[]
int[] modes = new int[result.size()];
for (int i = 0; i < result.size(); i++) {
modes[i] = result.get(i);
}
return modes;
}
// 递归中序遍历
private void inorder(TreeNode node) {
if (node == null) return;
// 先遍历左子树
inorder(node.left);
// 访问当前节点时更新 count / maxCount / result
if (pre == null) {
// 第一个被访问的节点
count = 1;
} else if (pre.val == node.val) {
// 与前一个节点值相同就累加
count++;
} else {
// 值变了重置计数为 1
count = 1;
}
pre = node; // 记录上一个节点
// 根据当前 count maxCount 更新结果
if (count == maxCount) {
result.add(node.val);
} else if (count > maxCount) {
maxCount = count;
result.clear();
result.add(node.val);
}
// 再遍历右子树
inorder(node.right);
}
}

View File

@ -0,0 +1,35 @@
package tree;
/**
* 题目701. 二叉搜索树中的插入操作 (insertIntoBST)
* 描述给定二叉搜索树BST的根节点 root 和要插入树中的值 value 将值插入二叉搜索树 返回插入后二叉搜索树的根节点 输入数据 保证 新值和原始二叉搜索树中的任意节点值都不同
* 注意可能存在多种有效的插入方式只要树在插入后仍保持为二叉搜索树即可 你可以返回 任意有效的结果
*
* 示例 1
输入root = [4,2,7,1,3], val = 5
输出[4,2,7,1,3,5]
解释另一个满足题目要求可以通过的树是
* 链接https://leetcode.cn/problems/insert-into-a-binary-search-tree/
*/
public class InsertIntoBST {
public TreeNode insertIntoBST(TreeNode root, int val) {
if (root == null) return new TreeNode(val);
TreeNode newRoot = root;
TreeNode pre = root;
while (root != null) {
pre = root;
if (root.val > val) {
root = root.left;
} else if (root.val < val) {
root = root.right;
}
}
if (pre.val > val) {
pre.left = new TreeNode(val);
} else {
pre.right = new TreeNode(val);
}
return newRoot;
}
}

View File

@ -0,0 +1,35 @@
package tree;
/**
* 题目235. 二叉搜索树的最近公共祖先 (LowestCommonAncestor)
* 描述给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先
*
* 百度百科中最近公共祖先的定义为对于有根树 T 的两个结点 pq最近公共祖先表示为一个结点 x满足 x pq 的祖先且 x 的深度尽可能大一个节点也可以是它自己的祖先
*
* 例如给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5]
*
* 示例 1
输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
输出: 6
解释: 节点 2 和节点 8 的最近公共祖先是 6
* 链接https://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-search-tree/
*/
public class LowestCommonAncestor2 {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
// 如果 root null空树或者恰好碰到 p/q 中的一个就直接返回 root
if (root == null) {
return null;
}
// 由于是 BST可利用大小关系快速定位
if (root.val > p.val && root.val > q.val) {
// p q 都比 root LCA 在左子树
return lowestCommonAncestor(root.left, p, q);
} else if (root.val < p.val && root.val < q.val) {
// p q 都比 root LCA 在右子树
return lowestCommonAncestor(root.right, p, q);
} else {
// 否则root 已经是 pq 的分叉点或者 root 等于 p q就是 LCA
return root;
}
}
}

View File

@ -0,0 +1,26 @@
package tree;
/**
* 题目617. 合并二叉树 (mergeTrees )
* 描述给你两棵二叉树 root1 root2
* 想象一下当你将其中一棵覆盖到另一棵之上时两棵树上的一些节点将会重叠而另一些不会你需要将这两棵树合并成一棵新二叉树合并的规则是如果两个节点重叠那么将这两个节点的值相加作为合并后节点的新值否则不为 null 的节点将直接作为新二叉树的节点
* 返回合并后的二叉树
* 注意: 合并过程必须从两个树的根节点开始
*
* 示例 1
输入root1 = [1,3,2,5], root2 = [2,1,3,null,4,null,7]
输出[3,4,5,5,4,null,7]
* 链接https://leetcode.cn/problems/merge-two-binary-trees/
*/
public class MergeTrees {
// 递归
public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
if (root1 == null) return root2;
if (root2 == null) return root1;
root1.val += root2.val;
root1.left = mergeTrees(root1.left,root2.left);
root1.right = mergeTrees(root1.right,root2.right);
return root1;
}
}