当前位置: 首页剑指offer刷题第三期问题详情 【二叉树专题】剑指 Offer 68 – I. 二叉搜索树的最近公共祖先 本问题对应课程链接:剑指offer刷题第三期 要求: 1、请打卡你的解题代码,如果能简单说一下思路则简单说一下思路。 2、给出你代码所用的时间复杂度和空间复杂度
共以下 34 个回答
“`java
找到分叉的节点
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (p.val >= root.val && q.val <= root.val || p.val <= root.val && q.val >= root.val) {
return root;
}
if (p.val > root.val && q.val > root.val) {
return lowestCommonAncestor(root.right, p, q);
} else {
return lowestCommonAncestor(root.left, p, q);
}
}
}
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
}
悲伤
时间复杂度和空间都为On
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
while(root!=null)
{
if(p.val>root.val&&q.val>root.val){
}
【思路】从根节点往树的末端遍历,当p、q的值介于一个节点的两端时,该节点即最近公共祖先
【复杂度】时间复杂度平均O(logn),最差O(n);空间复杂度O(1)
时间复杂度logn最差位O(n)
空间复杂度logn最差为O(n)
这段代码实现了在二叉搜索树中找到两个节点的最近公共祖先。代码中提供了两种解法:迭代法和递归法。
迭代法中,首先判断根节点和目标节点的大小关系,如果目标节点都比根节点大,则最近公共祖先一定在右子树中;如果目标节点都比根节点小,则最近公共祖先一定在左子树中。如果目标节点一个大一个小,则当前根节点就是最近公共祖先。根据这个规律,通过迭代遍历树,找到最近公共祖先节点,并返回。
递归法中,也是通过比较目标节点和根节点的大小关系来确定最近公共祖先的位置。如果目标节点都比根节点大,则递归调用函数,在右子树中继续查找。如果目标节点都比根节点小,则递归调用函数,在左子树中继续查找。如果目标节点一个大一个小,或者其中一个节点就是根节点,则当前根节点就是最近公共祖先。根据这个规律,通过递归遍历树,找到最近公共祖先节点,并返回。
在主函数中,首先创建了一个二叉搜索树,并给定了要查找最近公共祖先的两个节点p和q。然后根据选择的解法创建一个Solution或Solution2的实例,并调用lowestCommonAncestor函数来找到最近公共祖先节点。最后输出结果。
代码中还包含了释放内存的部分,用于释放创建的二叉树节点的内存。
总结来说,这段代码实现了在二叉搜索树中找到两个节点的最近公共祖先,并提供了迭代法和递归法两种解法。
时间复杂度为O(N)
空间复杂度为O(1)
递归实现,时间和空间复杂度都是O(n)
复杂度
时间复杂度: $O(n)$
空间复杂度: $O(1)$
Code
两个节点一定一个比该公共节点小,一个比该公共节点大,而且这样找到的第一个节点一定是最近公共祖先
时间复杂度 O(n) 空间复杂度 O(1)
思路:根据二叉搜索树的大小性质,以此选择左右子树进行遍历
时间复杂度:O(n) 空间复杂度:O(1)
递归
递归
时间复杂度O(n)
学到了
时间复杂度O(N)
空间复杂度O(1)
一次遍历
时间:O(n)
空间:O(1)
c++回溯法
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(rootp||rootq||rootNULL)return root;
TreeNode* left = lowestCommonAncestor(root->left,p,q);
TreeNode* right = lowestCommonAncestor(root->right,p,q);
if(left!=NULL&&right!=NULL)return root;
if(leftNULL&&right!=NULL)return right;
else if(left!=NULL&&rightNULL)return left;
else return NULL;
}
判断房最后就不需要考虑左大右小 或 左小右大
C++实现
一次遍历
从上往下遍历,遇到第一个结点的值在p和q之间就是最近公共祖先
复杂度O(n)
时空复杂度O(n)
1、该题不用递归,需要找到root在p、q中间时的节点,只需要在root非空时遍历,根据root与pq值大小比较更新root即可
时间复杂度:O(n)
空间复杂度:O(n)
时间复杂度:O(n)
空间复杂度:O(1)
时间O(n) 空间O(1)
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; //处理根节点
};
MY遇到一个节点的左子树里有p,右子树里有q,那么当前节点就是最近公共祖先。
时间复杂度:最差为 O(n),平均为 logn
空间复杂度:最差为 O(n),平均为 logn