LeetCode | 树
剑指 Offer 68 - II. 二叉树的最近公共祖先
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
示例:
输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
输出: 3
解释: 节点 5 和节点 1 的最近公共祖先是节点 3。
思路:
对于遍历的每一个节点,用left和right接收其左侧和右侧p和q存在的情况
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 root;
if(left==null && right==null) return null;
return left==null? right:left;
}
}
时间:设N为二叉树的节点数。最坏情况下,二叉树的所有节点都会被访问一次,时间复杂度为
O
(
N
)
O(N)
O(N)。
空间:空间复杂度取决于递归调用的栈深度,而栈深度取决于二叉树的高度,最坏情况下二叉树为一条链,此时高度为 N,空间复杂度为
O
(
N
)
O(N)
O(N)。
剑指 Offer 68 - I. 二叉搜索树的最近公共祖先
给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。
思路:
二叉搜索树相比二叉树多了排序的条件,因此实现起来应该更简单
下面是一次遍历法
从root出发,寻找p和q第一次出现在当前节点的左右左右子树的地方
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
TreeNode lcAncestor=root;
while(true){
if(p.val<lcAncestor.val && q.val < lcAncestor.val){
lcAncestor=lcAncestor.left;
}else if(p.val>lcAncestor.val && q.val > lcAncestor.val){
lcAncestor=lcAncestor.right;
}else{
break;
}
}
return lcAncestor;
}
}
时间:设N为二叉树的节点数。上述代码需要的时间与节点 p和 q 在树中的深度线性相关,最坏的情况下,树呈现链式结构,p和 q一个是树的唯一叶子结点,一个是该叶子结点的父节点,此时时间复杂度为
O
(
N
)
O(N)
O(N)。
空间:
O
(
1
)
O(1)
O(1)。