6.3 树
This commit is contained in:
parent
5b858edaa8
commit
566e4136f5
79
src/main/java/tree/FindMode.java
Normal file
79
src/main/java/tree/FindMode.java
Normal 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);
|
||||
}
|
||||
}
|
35
src/main/java/tree/InsertIntoBST.java
Normal file
35
src/main/java/tree/InsertIntoBST.java
Normal 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;
|
||||
}
|
||||
}
|
35
src/main/java/tree/LowestCommonAncestor2.java
Normal file
35
src/main/java/tree/LowestCommonAncestor2.java
Normal file
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
26
src/main/java/tree/MergeTrees.java
Normal file
26
src/main/java/tree/MergeTrees.java
Normal 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;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user