第九天打卡

530.二叉搜索树的最小绝对差 

 方法1、利用二叉排序树的特性

先递归得到一个有序数组,再取数组中差值最小的两个数

方法2、递归遍历过程中,通过双指针在遍历的同时,获得前后两个数值的差,并取最小值。


501.二叉搜索树中的众数 

 方法1:暴力法

拓展map的entrySet()函数以及hashmap的排序问题

先将entrySet集合变为stream流,再排序(降序),再collect转为list类型。

List<Map.Entry<Integer, Integer>> mapList = map.entrySet().stream()
				.sorted((c1, c2) -> c2.getValue().compareTo(c1.getValue()))
				.collect(Collectors.toList());

排序规则: 

 public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2)
    {
         //按照value值,重小到大排序
         //return o1.getValue() - o2.getValue();

         //按照value值,从大到小排序
         //return o2.getValue() - o1.getValue();

         //按照value值,用compareTo()方法默认是从小到大排序
         return o1.getValue().compareTo(o2.getValue());
     }

mapToInt:list使用mapToInt将list.stream流改造成Integer流。

Integer::intValue:调用Integer类中的intValue方法,将Integer对象中的值返回,转换成int类型。

toArray():list最终转为数组。

return list.stream().mapToInt(Integer::intValue).toArray();

方法2:利用二叉搜索树的特性

需要用到count和maxCount两个变量。

maxCount获取最大频率。当count>maxCount时,令maxCount=count,同时刷新结果集,放入当前结点。

if (count > maxCount) { // 如果计数大于最大值
    maxCount = count;   // 更新最大频率
    result.clear();     // 很关键的一步,不要忘记清空result,之前result里的元素都失效了
    result.push_back(cur->val);
}

538.把二叉搜索树转换为累加树 

利用二叉搜索树的特性。翻转中序遍历,利用双指针pre和cur,进行二叉树的遍历并更新数值。


小结

前一天的98.验证二叉搜索树、今天的530.二叉搜索树的最小绝对差501.二叉搜索树中的众数、538.把二叉搜索树转换为累加树都是相似类型的题目。

同样是用到了双指针,前结点pre以及二叉搜索树的特性。 


236. 二叉树的最近公共祖先

后序递归遍历 

递归函数什么时候需要返回值?什么时候不需要返回值?这里总结如下三点: 

  • 如果需要搜索整棵二叉树不用处理递归返回值,递归函数就不要返回值(第八天打卡的113.路径总和ii)
  • 如果需要搜索整棵二叉树且需要处理递归返回值,递归函数就需要返回值。 (这种情况是在本题中介绍)
  • 如果要搜索其中一条符合条件的路径,那么递归一定需要返回值,因为遇到符合条件的路径了就要及时返回。(第八天打卡的112.路径总和)

情况一:如果找到一个节点,发现左子树出现结点p,右子树出现节点q,或者 左子树出现结点q,右子树出现节点p,那么该节点就是节点p和q的最近公共祖先。

情况二:节点本身q,它拥有一个子孙节点p。

情况一和情况二代码实现过程都是一样的。

在实现情况一的逻辑中遇到 q 就返回,不会再向下遍历子结点。

同样情况二中,q结点是p结点的祖先,当遇到祖先q时,可以直接返回祖先

也可以说,实现情况一的逻辑,顺便包含了情况二这种 q 或者 p 本身就是公共祖先的情况

接下来就是递归三步走。

1、明确参数和返回值

2、明确终止条件

3、明确单次逻辑


235. 二叉搜索树的最近公共祖先 

因为是有序树,所以如果中间节点是q和p的公共祖先,那么中间节点的数值一定是在[p, q]区间的。即 p < 中节点 < q 或者 q < 中节点 < p

那么只要从上到下去遍历,遇到 cur节点是数值在[p, q]区间中则一定可以说明该节点cur就是q 和 p的公共祖先。 那问题来了,一定是最近公共祖先吗

如图: 如果从节点5继续向左遍历,那么将错过成为q的祖先, 如果从节点5继续向右遍历则错过成为p的祖先。

所以:当我们从上向下去递归遍历,第一次遇到cur节点的数值在[p, q]区间中,那么cur就是 p和q的最近公共祖先。


701.二叉搜索树中的插入操作

常规的递归题,利用二叉搜索树的有序特性。


450.删除二叉搜索树中的节点 

删除二叉搜索树的一个结点,有5种情况

1、没有找到删除结点,返回null/root

2、删除结点3,左右节点都不为空,把该节点的左孩子放入右孩子最左结点的左孩子上,返回该节点右孩子成为新的根节点

3、删除节点的左右结点都为空,直接删除,返回null

4、删除结点的左孩子为空,右孩子不为空,返回右孩子作为新的根节点

5、删除节点的右孩子为空,左孩子不为空,返回左孩子作为新的根节点

普通二叉树的删除方式:

没记,待刷


669. 修剪二叉搜索树 

这一块递归有点难想。假设给定[1, 3]区间,在二叉搜索树的中可不是单纯的节点3和左孩子节点0就决定的,还要考虑节点0的右子树以及节点4的左子树。

如何进行修剪:

1、把小于区间的节点0的右孩子节点2 直接赋给节点3的左孩子(即把节点0从二叉树中移除)

2、把大于区间的节点4的左孩子节点直接赋给节点3的右孩子

如下代码相当于把节点0的右孩子(节点2)返回给上一层

if (root.val < low) {
    TreeNode right = trimBST(root.right, low, high); // 寻找符合区间[low, high]的节点
    return right;
}

 然后如下代码相当于用节点3的左孩子,把下一层返回的节点0的右孩子(节点2) 接住

root.left = trimBST(root.left, low, high);

此时就完成了对结点0的移除。


108.将有序数组转换为二叉搜索树 

其实就是简单的二分查找,但是因为不熟悉,所以错误百出。

1、递归结束条件不知道该怎么写。(递归结束条件是:left > right)递归到只剩下一个元素时,left与right指针是指向同一个元素的

2、区间定义,是左闭右闭,还是左闭右开有点混乱。(一刷规定左闭右闭[0, nums.length - 1]

但是

如果区间定义的是左闭右开[0, nums.length],递归结束条件就是left >= right

避免记混,按照左闭右闭的情况刷题,左闭右开不要记。 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值