LCA 类问题
时间复杂度 O(n),如果 Tree 的形状是一条线往左或右的 full binary tree 的话。
public class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
// Got to check if p and q is null as well;
if(root == null) return root;
if(root.val > p.val && root.val > q.val)
return lowestCommonAncestor(root.left, p, q);
if(root.val < p.val && root.val < q.val)
return lowestCommonAncestor(root.right, p, q);
return root;
}
}因为是尾递归,显而易见的改法是用 while循环省去递归占用的系统栈空间;
这种解法的时间复杂度是 O(n log n),因为对于一个 node 来讲,它被 check 的次数等于它和 root 的距离 (也就是 height)。
极少会有 O(n^2) 的 binary tree 算法,因为那意味着每个节点相对于整个树重新计算,而不再是自己从属的路径或者高度。
时间复杂度 O(n),相对于每个 node 来讲,只会被函数调用和计算一次。
另一种时间复杂度的分析方式是,这题的递归结构不过是个 post-order traversal,遍历的复杂度当然是 O(n).
想到这,迭代的写法也比较明显了,写个 post-order traversal 就行。
其实就是 inorder pre-process 了一遍之后,把 binary tree 当 BST 用。因为 in-order 的 index 就像 BST 里的大小一样,可以直接确定几个节点在树中的相对位置。同时因为我们都是从 root 开始一层一层往下搜索的,也能保证每次循环的 root 都一定 valid.
这个写法只能算是个有意思的迭代思路,空间时间耗费都挺大的,代码量也长,如果追求速度与效率的话,就不要用这个写法骗自己。。
不过如果在同一个 Tree 上要跑好多次 LCA,这个做法还是比较可取的~
给一个 二叉树 , 求最深节点的最小公共父节点。
这题的关键点只有一个:意识到只需要求最底层 level 最左面和最右面节点的 LCA 就可以了。
因此这个问题的递归与迭代就变成了两个子问题:
Last updated