一、二叉搜索树的最小绝对差
题目链接
思路: 中序遍历保留为list + for循环找最小绝对差
二叉搜索树中序遍历后是有序的数组!!
注意:i = 1开始遍历
解法:
public int getMinimumDifference(TreeNode root) {
List<Integer> res = new ArrayList<>();
inorder(root, res);
int num = Integer.MAX_VALUE;
for (int i = 1; i < res.size(); i++) {
if (num > res.get(i) - res.get(i - 1))
num = res.get(i) - res.get(i - 1);
}
return num;
}
private void inorder(TreeNode root, List<Integer> res) {
if (root == null)
return;
inorder(root.left, res);
res.add(root.val);
inorder(root.right, res);
}
二、二叉搜索树中的众数
题目链接
思路:中序遍历的迭代法(stack);
注意:
pre是cur的前驱结点,便于比较
更新count时要注意count=maxcount的情况;
当出现count>maxcount时需要清空原先列表中保存的元素
解法:
public int[] findMode(TreeNode root) {
TreeNode pre = null;
Stack<TreeNode> stack = new Stack<>();
// 结果列表
List<Integer> res = new ArrayList<>();
TreeNode cur = root;
int count = 0;
int maxcount = 0;
while (cur != null || !stack.isEmpty()){
if (cur != null){
stack.push(cur);
cur = cur.left;
}else{
cur = stack.pop();
// 判断当前节点是否出现过 或者 当前节点值与上一个节点值是否相等
if (pre == null || cur.val != pre.val)
count = 1;
else
count++;
// 更新count
if (count > maxcount){
maxcount = count;
res.clear();
res.add(cur.val);
}else if (count == maxcount){
res.add(cur.val);
}
// 及时更新
pre = cur;
cur = cur.right;
}
}
// 使用stream()做数据映射
// mapToInt:一个流中的元素转换为 int 类型
// 双冒号就是把方法当做参数传到stream内部,使stream的每个元素都传入到该方法里面执行一下
// 最后转换为array类型
return res.stream().mapToInt(Integer::intValue).toArray();
}
三、二叉树的最近公共祖先
题目链接
思路:使用后序遍历(即回溯),
注意:
还有一个情况,就是节点本身p,它拥有一个子孙节点q。
在回溯的过程中,必然要遍历整棵二叉树,即使已经找到结果了,依然要把其他节点遍历完,因为要使用递归函数的返回值(也就是代码中的left和right)做逻辑判断。
理解如果返回值left为空,right不为空为什么要返回right,为什么可以用返回right传给上一层结果。
过程图:(见代码随想录https://programmercarl.com/0236.%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E6%9C%80%E8%BF%91%E5%85%AC%E5%85%B1%E7%A5%96%E5%85%88.html#java)
解法:
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null || root == p || root == q)
return root;
TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);
// 若未找到节点 p 或 q
if (left == null && right == null){
return null;
}else if (left == null && right != null){
return right;
}else if (left != null && right == null){
return left;
}else // 返回的节点都不为空,说明这两个节点就是p和q;
return root;
}
四、二叉搜索树的最近公共祖先
题目链接
思路:还是后序遍历 ;或者同上题,直接可以用上次代码
注意:只要当cur节点在区间(p->val <= cur->val && cur->val <= q->val)
或者 (q->val <= cur->val && cur->val <= p->val)中,那么cur就是最近公共祖先了,直接返回。
解法:
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root.val > p.val && root.val > q.val) return lowestCommonAncestor(root.left, p, q);
if (root.val < p.val && root.val < q.val) return lowestCommonAncestor(root.right, p, q);
return root;
}