代码随想录算法训练营第二十一天 | LeetCode530.二叉搜索树的最小绝对差、LeetCode501.二叉搜索树中的众数、LeetCode236.二叉树的最近公共祖先

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

题目链接:530.二叉搜索树的最小绝对差

【解题思路】

  • 用双指针法,一个记录当前节点,一个记录当前节点的下一个节点,再用一个变量存最小值。

【解题步骤】

  • 主函数部分:

    • 【全局变量】定义一个result,初始化为最小数,记录相邻结点差值的最小值

    • 【全局变量】定义一个指针,初始为空

  • 递归函数部分:

    • 1.确定参数以及返回值:

      • 返回值:

      • 参数:

        • 当前遍历到的结点cur

    • 2.确定递归终止条件:

      • 如果cur为空,return;

    • 3.处理单层递归逻辑:

      • 左:

        • 向左递归遍历,传入当前节点的左孩子

      • 中:

        • 如果pre不为空:

          • 对比result与(当前遍历节点 - 上一个遍历节点),取最小值存入result里

        • 让pre更新到cur当前位置,cur向下一层递归

      • 右:

        • 向右递归遍历,传入当前节点的右孩子

【代码部分】

java:

class Solution {
        TreeNode pre = null;
        int result = Integer.MAX_VALUE;
    public int getMinimumDifference(TreeNode root) {
        maxMin(root);
        return result;
    }
    public void maxMin(TreeNode cur){
        if(cur == null)return;
        maxMin(cur.left);
        if(pre != null) {
            result = Math.min(result, (cur.val - pre.val));
        }
        pre = cur;
        maxMin(pre.right);
    }
}

LeetCode 501 二叉搜索树中的众数

题目链接:501.二叉搜索树中的众数

【解题思路】

利用二叉搜索树的有序性,创建双指针,用计数器记录两个指针相等的次数

【解题步骤】

  • 主函数部分:

    • 【全局变量】定义一个count,初始化为0,统计单个元素出现的频率

    • 【全局变量】定义一个maxCount,统计整个二叉树里元素出现的最高频率

    • 【全局变量】定义一个result数组,存放结果集

    • 【全局变量】定义一个指针,初始为空

  • 递归函数部分:

    • 1.确定参数以及返回值:

      • 返回值:

      • 参数:

        • 二叉树的根节点cur

    • 2.确定递归终止条件:

      • 如果cur为空,return;

    • 3.处理单层递归逻辑:

      • 左:

        • 向左递归遍历,传入当前节点的左孩子

      • 中:

        • 判断pre是否为空:

          • 为空,说明我们遍历的是第一个元素,count=1;

          • 非空,且pre的数值与cur的数值相同:说明该元素重复出现一次,count+1;

          • 非空,且pre的数值与cur的数值不同:说明前一个元素和当前元素不相等,count = 1

        • 让pre更新到cur当前位置,cur向下一层递归

        • 如果我们当前统计单个元素的频率等于最高元素出现的频率:

          • 将当前元素的数值放入结果集

        • 如果我们当前统计单个元素的频率大于最高元素出现的频率:

          • 更新maxCount的数值

          • 清空结果集

          • 将当前元素的数值放入结果集

      • 右:

        • 向右递归遍历,传入当前节点的右孩子

【代码部分】

java:

class Solution {
		ArrayList<Integer> result = new ArrayList<>();
        int maxCount = 0;
        int count = 0;
        TreeNode pre = null;
    public int[] findMode(TreeNode root) {
        findM(root);
        int[] res = new int[result.size()];
        for(int i = 0; i < result.size(); i++){
            res[i] = result.get(i);
        }
        return res;
    }

    public void findM(TreeNode cur){
        if(cur == null)return;

        findM(cur.left);

        if(pre == null || cur.val != pre.val){
            count = 1;
        }else{
            count ++;
        }

        if(count == maxCount){
            result.add(cur.val);
        }else if(count > maxCount){
            maxCount = count;
            result.clear();
            result.add(cur.val);
        }
        pre = cur;
        findM(cur.right);
    }
}

【疑难点】

  • 哪里体现我们利用了二叉搜索树的有序性?

    • 因为二叉搜索树是有序的,因此重复的元素必为相邻的元素,利用这一点,可以只需要一次遍历就求出出现最大的元素

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

题目链接:236. 二叉树的最近公共祖先

【解题思路】

  • 从下往上遍历,两个节点第一个交汇点即为最近公共祖先

  • 采用后序遍历,用回溯的过程实现从下往上遍历

【解题步骤】

  • 递归函数部分

    • 1.确定参数以及返回值:

      • 返回值:

        • 公共祖先节点

      • 参数:

        • 根节点root

        • 两个需要判断的节点p,q

    • 2.确定递归终止条件:

      • 如果root为空,return root;

      • 如果root等于p或q,return root;

    • 3.处理单层递归逻辑:

      • 左:

        • 创建一个TreeNode节点left,用来接收向左递归返回的值

      • 右:

        • 创建一个TreeNode节点right,用来接收向右递归返回的值

      • 中:

        • 判断左右是否为空:

          • 都不为空,说明当前的root为公共祖先,return root

          • 一边为空,另一边不为空,返回不为空的那个节点

          • 都为空,return null

【代码部分】

java:

class Solution {
    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);

		if(left == null && right == null)return null;
		else if(left != null && right == null)return left;
		else if(right != null && left == null)return right;
		else return root;
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值