当前位置: 首页剑指offer刷题第四期问题详情 【二叉树专题】剑指 Offer 68 – I. 二叉搜索树的最近公共祖先 本问题对应课程链接:剑指offer刷题第四期 要求: 1、请打卡你的解题代码,如果能简单说一下思路则简单说一下思路。 2、给出你代码所用的时间复杂度和空间复杂度
共以下 31 个回答
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
//bstree 自顶而下判断两个结点是否在一个根节点不同的子树中
//二叉搜索树 最近的公共结点一定在[p,q]区间内,闭区间是因为可能其中一个是另外一个的祖先
class Solution {
private:
TreeNode* res = new TreeNode(-1);
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
check(root, p, q);
return res;
};
循环迭代
如果p、q在root的同侧,则继续往下遍历
如果p、q在root的异侧,则说明root是最近公共祖先
由于二叉搜索树的性质,通过val大小可以判断位置
ts
时间复杂度:最差O(n)平均O(logn)
空间复杂度:最差O(n)平均O(logn)
思路:该树是二叉搜索树,所以给定一个节点可以从树的根节点找到到它的路径,所以将题目给定的两个节点的路径中找到,然后找到这两个节点路径中最后一个相同的节点就是他们的最近公共祖先
c++ 代码 递归val&&root->valval)
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q)
{
while(root)
{
if(root->val>p->val&&root->val>q->val)
root=root->left;
else if(root->val
root=root->right;
else
break;
}
};
要充分利用二叉搜索树的特性, 我以为又要用递归呢
利用数值关系和唯一性。时间O(n) 空间O(1)
代码
十
/**
* 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) {
if (p.val > q.val) {
TreeNode tmp = p;
p = q;
q = tmp;
}
while (root != null) {
if (root.val < p.val) root = root.right;
else if (root.val > q.val) root = root.left;
else break;
}
return root;
}
}
利用规律做
“`typescriptfunction lowestCommonAncestor(root: TreeNode | null, p: TreeNode | null, q: TreeNode | null): TreeNode | null {
let cur = root;
while(true) {
if(cur.val < p.val && cur.val < q.val) { cur = cur.right; } else if ( cur.val > p.val && cur.val > q.val) {
cur = cur.left;
} else {
break;
}
}
return cur;
};
“`
”’java
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
//最近公共祖先
if(root null){
return null;
}
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;
}
}
时间复杂度O(n)
空间复杂度O(1)
”’
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
//常规二叉树找公共祖先 回溯往上
if(rootnull||rootp||rootq)
{
return root;
}
TreeNode left = lowestCommonAncestor(root.left,p,q);
TreeNode right = lowestCommonAncestor(root.right,p,q);
if(leftnull&&rightnull)
{
return null;
}
if(left!=null&&right!=null)
{
return root;
}
if(left!=null)
{
return left;
}
if(right!=null)
{
return right;
}
return null;
}
}
时间复杂度:O(n);
空间复杂度:O(n);
思路
BST的特点是左子树都小于root,右子树都大于root。
所以从root开始遍历,只有三种情况:
1. 如果p和q都小于root,说明公共祖先节点在root的左侧
2. 如果p和q都大于root,说明公共祖先节点在root的右侧
3. 如果p和q分别在一左一右,说明当前就是公共祖先节点。
代码
递归
Definition for a binary tree node.
class TreeNode:
def init(self, x):
self.val = x
self.left = None
self.right = None
class Solution:
def lowestCommonAncestor(self, root: ‘TreeNode’, p: ‘TreeNode’, q: ‘TreeNode’) -> ‘TreeNode’:
if not root:
return root
if p.val <= root.val <= q.val or q.val <= root.val <= p.val:
return root
elif p.val <= root.val and q.val <= root.val:
return self.lowestCommonAncestor(root.left, p, q)
elif root.val <= p.val and root.val <= q.val:
return self.lowestCommonAncestor(root.right, p, q)
时间复杂度O(n)
空间复杂度O(n)
要么都在一边,这种情况,大了就减小,小了就增大
要么分两边,这种情况,找两边的最顶根节点就行
时间复杂度:O(n)
空间复杂度:O(n)
时间复杂度 O(N) 空间复杂度 O(1)
时间复杂度:O(n);
空间复杂度:O(n);
“`c++val && q->valval)return lowestCommonAncestor(root->left,p,q);
//利用二叉搜索树的性质
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(p->val
if(p->val>root->val && q->val>root->val)return lowestCommonAncestor(root->right,p,q);
return root;
}
};
7.17
Day10:下面是代码
时间复杂度:O(n)
空间复杂度:O(n)