二叉树的应用
530.二叉搜索树的最小绝对差
- 对于二叉搜索树而言, 中序遍历为升序, 所以最小绝对差出现在相邻的两个元素之间
- 递归中序遍历, 同时用前缀指针pre, 永远指向当前节点的上一个节点, 不断比较和记录最小绝对差, 同时更新前缀指针
代码:
class Solution {
int min_diff = 0x7fffffff;
TreeNode pre = null;
public int getMinimumDifference(TreeNode root) {
dfs(root);
return min_diff;
}
public void dfs(TreeNode root){
if(root == null) return;
dfs(root.left);
if(pre != null && root.val - pre.val < min_diff){
min_diff = root.val - pre.val;
}
pre = root;
dfs(root.right);
}
}
501.二叉搜索树的众数
- 递归中序遍历二叉树, 同时用前缀指针指向上一个节点, 遍历的同时记录当前元素个数和最大个数
- 当前元素个数 > 最大元素个数: 清空结果集, 将当前节点加入结果集
- 当前元素个数 = 最大元素个数: 将当前节点值继续加入结果集
代码:
class Solution {
List<Integer> list = new ArrayList<>();
TreeNode pre = null;
int cnt = 0, maxCnt = 0;
public int[] findMode(TreeNode root) {
dfs(root);
return list.stream().mapToInt(x->x).toArray();
}
// 注意处理边界节点的情况
public void dfs(TreeNode root) {
if(root == null) return;
dfs(root.left);
// pre == null, root则代表是第一个节点
if(pre == null) {
cnt = 1;
}else if(root.val == pre.val) {
cnt++;
}else cnt = 1;
if(cnt > maxCnt){
// 清空结果集
list.clear();
list.add(root.val);
// 更新最大cnt
maxCnt = cnt;
}else if(cnt == maxCnt){
// 相同次数, 再装入结果集
list.add(root.val);
}
// 更新指针指向
pre = root;
dfs(root.right);
}
}
236.二叉树的最近公共祖先
最近公共祖先求法: 对于一棵二叉树, 其中一个节点在其左子树上, 一个节点在其右子树上, 则当前节点为其最近公共祖先
- 需要知道子节点提供的信息, 所以需要后序遍历
- 子节点状态: 1: 代表找到目标节点 0: 代表只找到一个目标节点 -1: 代表未找到任何一个目标节点
代码:
class Solution {
// 对于一棵二叉树, 其中一个节点在其左子树上, 一个节点在其右子树上
// 则当前节点为其最近公共祖先
TreeNode t = null;
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
dfs(root, p, q);
return t;
}
// 当前节点的信息需要子节点提供:---需要后序遍历
public int dfs(TreeNode root, TreeNode p, TreeNode q) {
if(root == null) return -1;
int left = dfs(root.left, p, q);
int right = dfs(root.right, p, q);
// 1: 代表找到目标节点 0: 代表只找到一个目标节点 -1: 代表未找到任何一个目标节点
if(left == 1 || right == 1) return 1;
if(root == p || root == q) {
if(left == 0 || right == 0){
t = root;
return 1;
}else return 0;
} else {
if(left == 0 && right == 0) {
t = root;
return 1;
}else if(left == 0 || right == 0){
return 0;
}else return -1;
}
}
}