题解27 | 递归非递归方法#二叉树中找两节点的最近公祖先#
在二叉树中找到两个节点的最近公共祖先
https://www.nowcoder.com/practice/e0cc33a83afe4530bcec46eba3325116
class Solution { public: /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param root TreeNode类 * @param o1 int整型 * @param o2 int整型 * @return int整型 */ TreeNode * LCA(TreeNode* root, int o1, int o2){ if(root == NULL || root->val == o1 || root->val == o2){ return root; } TreeNode *l = LCA(root->left, o1, o2); TreeNode *r = LCA(root->right, o1, o2); if(l != NULL && r != NULL) { return root; } if(l != NULL) { return l; } if(r != NULL) { return r; } //都空的话 return NULL; } int lowestCommonAncestor(TreeNode* root, int o1, int o2) { // write code here TreeNode * anc = LCA(root,o1,o2); return anc->val; } };
算法基本思想:
①在函数LCA中,我们首先判断当前节点是否为空或者等于o1或o2的值,如果是的话,直接返回当前节点。然后递归调用左子树和右子树,得到它们的返回结果。根据左右子树的返回结果,可以确定最近公共祖先节点的位置。如果左右子树的返回结果都不为空,则当前节点为最近公共祖先节点。如果只有左子树的返回结果不为空,则左子树的返回结果为最近公共祖先节点。如果只有右子树的返回结果不为空,则右子树的返回结果为最近公共祖先节点。如果左右子树的返回结果都为空,则返回空。
②最后,在函数lowestCommonAncestor中,我们调用LCA函数来获取最近公共祖先节点,并返回其值。
时间复杂度:
这个算法的时间复杂度是O(N),其中N是二叉树中的节点数。因为每个节点都会被访问一次,所以总共需要遍历所有的节点。
空间复杂度:
空间复杂度是O(H),其中H是二叉树的高度。在递归调用中,需要使用系统栈来保存递归调用的上下文,所以空间复杂度取决于递归的深度,即二叉树的高度。
补充:递归实现
/** * struct TreeNode { * int val; * struct TreeNode *left; * struct TreeNode *right; * }; */ /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * @param root TreeNode类 * @param p int整型 * @param q int整型 * @return int整型 */ int lowestCommonAncestor(struct TreeNode* root, int p, int q ) { // write code here 3<=节点总数<=10000 非递归设立路径数组的参见C++方法 if (p > root->val && q < root->val || p < root->val && q > root->val) { return root->val; } else if (p < root->val && q < root->val) { return lowestCommonAncestor(root->left, p, q); } else if (p > root->val && q > root->val) { return lowestCommonAncestor(root->right, p, q); } //任何p、q有与根节点值相同的情况直接返回根节点值 return root->val; }
基本算法思想:
1. 首先判断p和q与根节点root的值的关系,如果p和q分别位于root的左右子树,或者其中一个等于root的值,那么root就是最近的公共祖先节点,直接返回root的值。
2. 如果p和q都小于root的值,说明p和q都位于root的左子树中,那么递归调用函数,传入root的左子节点和p、q的值,继续在左子树中寻找最近公共祖先节点。
3. 如果p和q都大于root的值,说明p和q都位于root的右子树中,那么递归调用函数,传入root的右子节点和p、q的值,继续在右子树中寻找最近公共祖先节点。
时间复杂度:
在最坏情况下,如果树是一个完全不平衡的二叉搜索树,即树的高度为N(节点总数),那么最坏情况下,每次递归调用只能排除一个节点,需要遍历整个树才能找到最近公共祖先节点。所以时间复杂度是O(N)。
空间复杂度:
递归调用的空间复杂度取决于递归的深度,即树的高度。在最坏情况下,如果树是一个完全不平衡的二叉搜索树,递归的深度为N,所以空间复杂度是O(N)。
本人考研刷算法题,立此专栏练习强化。