Leetcode 刷题笔记(十七) —— 二叉树篇之公共祖先问题

系列文章目录

一、 数组类型解题方法一:二分法
二、数组类型解题方法二:双指针法
三、数组类型解题方法三:滑动窗口
四、数组类型解题方法四:模拟
五、链表篇之链表的基础操作和经典题目
六、哈希表篇之经典题目
七、字符串篇之经典题目
八、字符串篇之 KMP
九、解题方法:双指针
十、栈与队列篇之经典题目
十 一、栈与队列篇之 top-K 问题
十 二、二叉树篇之二叉树的前中后序遍历
十 三、二叉树篇之二叉树的层序遍历及相关题目
十 四、二叉树篇之二叉树的属性相关题目
十 五、 二叉树篇之二叉搜索树的
十 六、 二叉树篇之二叉搜索树的属性
更新中 …


前言

刷题路线来自 :代码随想录

题录

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

Leetcode 链接
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

示例 1:
输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
输出:3
解释:节点 5 和节点 1 的最近公共祖先是节点 3 。

题解:
在这里插入图片描述

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        return dfs(root, p, q);
    }
    public TreeNode dfs (TreeNode root, TreeNode p, TreeNode q) {
    	// 终止条件,找到就返回找到的结点,没找到就返回 null
        if (root == null || root == p || root == q) {
            return root;
        }
        // 后序遍历
        // 接收到左右子树返回的结果
        TreeNode left = dfs(root.left, p, q);
        TreeNode right = dfs(root.right, p ,q);
        // 向上回溯
        // 左右各一个,返回当前根节点
        if (left != null && right != null) return root;
        // 一边为 null ,一边找到,返回找到的结点
        if (left == null && right != null) return right;
        if (left != null && right == null) return left;
        // 左右都为 null, 都每找到返回 null
        return null;
    }
}

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

Leetcode 链接
给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5]

示例 1:
输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
输出: 6
解释: 节点 2 和节点 8 的最近公共祖先是 6。

示例 2:
输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4
输出: 2
解释: 节点 2 和节点 4 的最近公共祖先是 2, 因为根据定义最近公共祖先节点可以为节点本身。

题解:
方式一:递归

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        return dfs(root, p, q);
    }
    public TreeNode dfs(TreeNode root, TreeNode p, TreeNode q) {
        if (root.val > p.val && root.val > q.val) {
        	// 根节点值大,p q 结点肯定在左边,返回向左递归的结果
            return dfs(root.left, p, q);
        }
        if (root.val < p.val && root.val <q.val) {
        	// 根节点值小,p q 结点肯定在左边,返回向右递归的结果
            return dfs(root.right, p ,q);
        }
        // 根节点在 p q 中间,或者根结点等于 p q 其中一个,就是 p q 的最近公共祖先
        return root;
    }
}

方式二:迭代

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        while (true) {
            if (root.val > p.val && root.val > q.val) {
            	// 根结点大,向左子树遍历
                root = root.left;
            } else if (root.val < p.val && root.val < q.val) {
            	// 根结点小,向右子树遍历
                root = root.right;
            } else {
            	// 根节点在中间,或者根结点等于 p q 其中一个
                break;
            }
        }
        return root;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值