面试题68-Ⅰ、68-Ⅱ

面试题68-Ⅰ.二叉搜索树的最近公共祖先

在这里插入图片描述
最近公共祖先的定义:设节点 root 为节点 p、q 的某公共祖先,若其左子节点 root.left 和右子节点 root.right 都不是 p、q 的公共祖先,则称 root 是最近的公共祖先

根据以上定义,若 root 是 p、q 的最近公共祖先,则只可能为以下情况之一:

1、p 和 q 在 root 的子树中,且分列 root 的异侧(即分别在左、右子树中);
2、p = root,且 q 在 root 的左或右子树中;
3、q = root,且 p 在 root 的左或右子树中;

在这里插入图片描述
则判断 p、q 与 root 的子树关系为:

  • 若 root.val < p.val,则 p 在 root 右子树中
  • 若 root.val > p.val,则 p 在 root 左子树中
  • 若 root.val = p.val,则 p 和 root 指向同一节点

迭代


class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
		while(root != null) {
			//根节点值小于两者的值,则说明在右子树中
			if(root.val < p.val && root.val < q.val) root = root.right;
			//根节点值大于两者的值,则说明在左子树中
			else if(root.val > p.val && root.val > q.val) root = root.left;
			else break;
		}
		return root;
	}
}
  • 时间复杂度 O(N) : 其中 N 为二叉树节点数;每循环一轮排除一层,二叉搜索树的层数最小为 logN (满二叉树),最大为 N (退化为链表)。
  • 空间复杂度 O(1) : 使用常数大小的额外空间。

递归

class Solution {
	//判断当前节点是否为p、q节点的共同祖先节点
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
		if(root == null) return root;
		//小于两个节点,则说明一定存在右子节点中
		if(root.val < q.val && root.val < p.val)
			return lowestCommonAncestor(root.right, p, q);
		else if(root.val > q.val && root.val > p.val)
			return lowestCommonAncestor(root.left, p, q);
		return root;
    }
}
  • 时间复杂度 O(N) : 其中 N 为二叉树节点数;每循环一轮排除一层,二叉搜索树的层数最小为 logN (满二叉树),最大为 N (退化为链表)。
  • 空间复杂度 O(N) : 最差情况下,即树退化为链表时,递归深度达到树的层数 N 。

————————————————————————————————————————

面试题68-Ⅱ.二叉树的最近公共祖先

在这里插入图片描述

1、如果当前根为 null,或者当前根为任意目标节点,递归结束,开始回溯

2、分别向左子树和右子树查询两个目标节点是否存在

3、若都没有查到,则表示当前树中,不存在目标节点

4、若其中一颗子树没有查到,则公共祖先为另一颗子树

5、若都查询到了,则目标节点在当前 root 的两侧,即:当前 root 为最近公共祖先

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
		if(root == null) return null;
		if(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;
		//若其中一颗子树没有查到,则公共祖先为另一颗子树
		if(left == null) return rigth;
		if(right == null) return left;
		//若都查询到了,则目标节点在当前 root 的两侧,即:当前 root 为最近公共祖先
		return root;
	}
}
  • 时间复杂度 O(N) : 其中 N 为二叉树节点数;最差情况下,需要递归遍历树的所有节点。
  • 空间复杂度 O(N) : 最差情况下,递归深度达到 N ,系统使用 O(N) 大小的额外空间。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值