No.1
题目
二叉搜索树的最小绝对差
思路
- 中序遍历的BST是有序序列
- 最小绝对差一定是在相邻的数组元素间
代码
public void inorderTraverse(TreeNode node, List<Integer> seq) {
if (node == null)
return;
inorderTraverse(node.left, seq);
seq.add(node.val);
inorderTraverse(node.right, seq);
}
public int getMinimumDifference(TreeNode root) {
List<Integer> inorderSeq = new ArrayList<>();
inorderTraverse(root, inorderSeq);
int min = Integer.MAX_VALUE;
for (int i = 1; i < inorderSeq.size(); i++) {
if (Math.abs(inorderSeq.get(i) - inorderSeq.get(i-1)) < min)
min = Math.abs(inorderSeq.get(i) - inorderSeq.get(i-1));
}
return min;
}
No.2
题目
二叉搜索树中的众数
思路
- 递归中序遍历BST,有序处理树中的众数
- 双指针,记录上一个访问的节点,用以和当前节点的值比较
- 众数有多个,如何处理?
- 当前count等于maxCount,则直接更新结果集
- 当前count大于maxCount,则更新maxCount,清空结果集,加入当前节点值
- 还挺想试试对任意树都适用的解法,利用优先队列,对频率排序
代码
private int maxCount = 0;
private int count = 0;
private List<Integer> result = new ArrayList<>();
private TreeNode pre = null;
public void searchBST(TreeNode cur) {
if (cur == null)
return;
// left
searchBST(cur.left);
// middle
if (pre == null) // pre为null,是第一次进入递归
count = 1;
else if (cur.val == pre.val) // 相等 频率+1
count++;
else // 不相等
count = 1;
pre = cur; // 更新pre
if (count == maxCount)
result.add(cur.val);
if (count > maxCount) {
maxCount = count;
result.clear();
result.add(cur.val);
}
// right
searchBST(cur.right);
}
public int[] findMode(TreeNode root) {
searchBST(root);
return result.stream().mapToInt(Integer::valueOf).toArray();
}
No.3
题目
二叉树的最近公共祖先
思路
递归分析
- 返回值:
Treenode
表示是否找到,参数:当前递归节点,节点p
和q
- 终止逻辑:当前递归节点等于
p
或q
,或为空
- 单层递归逻辑:左子树结果不为空,右子树为空,说明通过左子树返回,返回左子树递归结果;反之亦然;左右子树都不为空,说明当前递归节点就是公共祖先,返回当前节点;
代码
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == p || root == q || root == null)
return root;
TreeNode leftTree = lowestCommonAncestor(root.left, p, q);
TreeNode rightTree = lowestCommonAncestor(root.right, p, q);
if (leftTree != null && rightTree == null)
return leftTree;
if (rightTree != null && leftTree == null)
return rightTree;
if (leftTree != null && rightTree != null)
return root;
return null;
}