diff --git a/src/main/java/tree/FindMode.java b/src/main/java/tree/FindMode.java new file mode 100644 index 0000000..7076067 --- /dev/null +++ b/src/main/java/tree/FindMode.java @@ -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 result = new ArrayList<>(); // 存放众数的列表 + + public int[] findMode(TreeNode root) { + // 初始化(如果同一个 Solution 实例可能被重复调用,需要做清空) + maxCount = 0; + count = 0; + pre = null; + result.clear(); + + // 递归中序遍历 + inorder(root); + + // 把 List 转成 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); + } +} diff --git a/src/main/java/tree/InsertIntoBST.java b/src/main/java/tree/InsertIntoBST.java new file mode 100644 index 0000000..883e269 --- /dev/null +++ b/src/main/java/tree/InsertIntoBST.java @@ -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; + } +} diff --git a/src/main/java/tree/LowestCommonAncestor2.java b/src/main/java/tree/LowestCommonAncestor2.java new file mode 100644 index 0000000..b7cdc4c --- /dev/null +++ b/src/main/java/tree/LowestCommonAncestor2.java @@ -0,0 +1,35 @@ +package tree; +/** + * 题目:235. 二叉搜索树的最近公共祖先 (LowestCommonAncestor) + * 描述:给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。 + * + * 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 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 已经是 p、q 的分叉点(或者 root 等于 p 或 q),就是 LCA + return root; + } + } +} diff --git a/src/main/java/tree/MergeTrees.java b/src/main/java/tree/MergeTrees.java new file mode 100644 index 0000000..2c76bf1 --- /dev/null +++ b/src/main/java/tree/MergeTrees.java @@ -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; + } +}