题目概述(中等难度)
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 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 。
示例 2:
输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4 输出:5 解释:节点 5 和节点 4 的最近公共祖先是节点 5 。因为根据定义最近公共祖先节点可以为节点本身。
示例 3:
输入:root = [1,2], p = 1, q = 2 输出:1
题目链接:
点我进入leetcode
思路与代码
思路展现
这道题目的思路如下:
我们可以使用前序遍历的方式来解答题目:
1:假设此时我们的根节点root就是p或者q当中的一个,那么直接返回root即可.
2:如果不是,开始前序遍历,先把我们root的左子树的整体遍历完毕,如果root的左子树整体中包含了p和q,那么就说明p和q全部都在左子树的整体中,所以直接返回第一次找到的节点即可,这个节点就是我们的公共祖先.
3:如果根节点root的整体的右子树中有p和q,那么就说明p和q全部都在右子树的整体中,所以同样直接返回第一次找到的节点即可,这个节点就是我们的公共祖先.
4:如果p和q分别分布在根节点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) { return right; } if(right == null) { return left; } if(left != null && right != null) { return root; } return null; } }
时间复杂度:O(N),其中 N是二叉树的节点数。二叉树的所有节点有且只会被访问一次,因此时间复杂度为 O(N)。
空间复杂度:O(N),其中 N 是二叉树的节点数。递归调用的栈深度取决于二叉树的高度,二叉树最坏情况下为一条链,此时高度为 N,因此空间复杂度为 O(N)。
总结
这道题目算是面试中经常会考到的一道题目,希望大家可以重点掌握.