class Solution:
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
# 递归解法,本题应该注意是二叉搜索树,所以可以有此解法
def dfs(root: 'TreeNode')->'TreeNode':
nonlocal p,q
if (p.valroot.val) or (p.val>root.val and q.val
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
# 非递归解法 本质上与递归解法的思路是一样的,但是由于没有递归的调用栈,将空间复杂度降到了O(1),时间复杂度还是o(n),这个时间复杂度我不是很确定
tmp=root
while True:
if p.valtmp.val and q.val>tmp.val:
tmp=tmp.right
continue
elif p.val==tmp.val:
return p
elif q.val==tmp.val:
return q
else:
return tmp
另外一个题目,这个II
class Solution:
class Solution:
def lowestCommonAncestor(self, root: TreeNode, p: TreeNode, q: TreeNode) -> TreeNode:
# 和二叉搜索树的最近公共祖先一样,本质上都是递归
if not root:return
if root.val==p.val or root.val==q.val:
return root
left=self.lowestCommonAncestor(root.left,p,q)
right=self.lowestCommonAncestor(root.right,p,q)
if left and right:
return root
if not left:
return right
else:
return left
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
if not root : return root
while root:
if p.val<root.val and q.val<root.val:
root = root.left
elif p.val>root.val and q.val>root.val:
root = root.right
else:
return root
#######
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
if not root : return root
num,stark = root,[]
while num or stark:
while num:
stark.append(num)
if (num.val > p.val and num.val <q.val) or (num.val < p.val and num.val > q.val): return num
if num.val == p.val: return p
if num.val == q.val: return q
num = num.right
tem = stark.pop()
num = tem.left
return root
共以下 35 个回答
把握二叉搜索树的特点,元素之间存在大小关系。
开始奋发图强了
递归 DFS
迭代 思路相同
时间空间O(N)
时间复杂度 O(n)
空间复杂度 O(n)
没什么好说的
另外一个题目,这个II
思路一:利用二叉搜索树值的有序性:右子节点的值大于根节点的值,根节点的值大于左子树的值。root.val > q.val && root.val > p.val的情况下,到root的左子树去找;root.val < q.val && root.val < p.val的情况下,到root的右子树去找;root.val的值在[q.val, p.val]说明root就是q,p节点的最近公共祖先。放上递归实现。时间和空间复杂度都为O(N)。迭代实现的时间复杂度为O(N),空间复杂度为O(1)。
思路二:找到root到q节点的路径,用链表记录为pathQ;找到root到p节点的路径,用链表记录为pathP。这个问题就转换成找两个链表的第一个公共节点。时间复杂度O(N),空间复杂度O(N)。额外记录下:"= ="与equals的区别,如果是基本数据类型,比较值是否相等,如果是实例对象,则是比较两个对象的地址是否相等。equals如果是基本数据类型,无法使用,如果是实例对象,没有重写equals方法,与"= ="一样,因为没有重写equals方法,类默认继承Object类的equals方法,而Object类的equals方法是用"= ="实现。equals方法一般是比较对象的内容是否相等,一般需要自己重写equals方法。
时间复杂度:O(n)
空间复杂度:O(n)
思路:分三种情况:1.p和q分别在root的左右两边 2.p和q在root的左边 3.p和q在root的右边
时间复杂度 O(N)
空间复杂度 O(N)
用递归的思想解决
时间复杂度和空间复杂度都为O(N)
解题思路:根据p和q的值和搜索二叉树的性质,对二叉树进行遍历,直到节点值和目标值相等,得到搜索路径,两条搜索路径中第一个不相等的节点之前的节点就是公共祖先。
时间复杂度:O(n)
空间复杂度:O(n)
//递归遍历即可,因为是二叉搜索树,所以可以进行剪枝val&&root->valval ) res=lowestCommonAncestor(root->right,p,q);
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(!root) return root;
TreeNode* res=nullptr;
if(root->val>=p->val&&root->val<=q->val) res=root;
else if(root->val>=q->val&&root->val<=p->val) res=root;
else if(root->val
else res=lowestCommonAncestor(root->left,p,q);
return res;
};
思路:利用二叉搜索树的特性。左子树小于根节点,右子树大于根节点。进行判断p、q的最近公共祖先。
时间复杂度O(n),空间复杂度O(n)
时间:O(n)
空间:O(1)
时间复杂度O(n)
空间复杂度O(1)
画完图自己写的,看解析总结写出来
时间O(n),空间O(1)
画完图看了下这题看懂了图还是很简单的。主要是二叉搜索数的数值关系
时间O(n)
空间O(n)
迭代
先获得从根节点到达目标节点的路径,两个路径中最后重合的一个节点即为最近公共祖先
第一个方法,看的别人的,对二叉搜索树的数字不敏感啊,还是想着left和right,太菜啦,第二个是遍历模版,刚开始用left和right各种问题过不去,改为值比较就能过去了 时间复杂度O(n) 空间复杂度O(n)
时间复杂度 O(n) 最坏 退化为链表
时间:O(n),空间:O(1)
递归
时间复杂度O(n) 空间复杂度O(n) 系统栈
简单迭代
时间复杂度O(N)空间复杂度O(1)
时间复杂度:最差为 O(n),平均为 logn
空间复杂度:最差为 O(n),平均为 logn