235二叉搜索树的最近公共祖先
解法
跟普通二叉树的解法差不多,但是可以充分利用搜索二叉树的性质:从上到下遍历,如果某一个节点的值在p,q之间,那该节点一定是p和q的最近公共祖先。
solution
class Solution:
# 从上到下遍历,如果某一个节点的值在p,q之间,那该节点一定是p和q的最近公共祖先
def traversal(self,tree,p,q):
if tree==None:return None
if (tree.val>p.val and tree.val<q.val)or(tree.val>q.val and tree.val<p.val):return tree
# 1
if tree.val>p.val and tree.val>q.val:
leftres=self.traversal(tree.left,p,q)
else:
leftres=None
# 2
if tree.val<p.val and tree.val<q.val:
rightres=self.traversal(tree.right,p,q)
else:
rightres=None
# 3
if tree.val==p.val or tree.val==q.val:
return tree
if leftres!=None and rightres!=None:return tree
elif leftres!=None:return leftres
elif rightres!=None:return rightres
else:return None
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
return self.traversal(root,p,q)
701. 二叉搜索树中的插入操作
my problem
我发现我的问题是不知道递归的返回值怎么确定,递归的返回值怎么处理
返回值设置在哪里:出口的return和递归后的return怎么处理?
对于无返回值的函数:怎么规范?
solution(根据不断提交后的判分后边想边改出来的,这是不对的!面试这样会扣分!)
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def traversal(self,node,val):
if node==None:return
#后序遍历
if val<node.val:
self.traversal(node.left,val)
if val>node.val:
self.traversal(node.right,val)
#处理“中”
newnode=TreeNode(val)
if newnode.val<node.val and node.left==None:node.left=newnode
if newnode.val>node.val and node.right==None:node.right=newnode
return
def insertIntoBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
if root:
self.traversal(root,val)
return root
else:
root=TreeNode(val)
return root
看完讲解视频后
- 二叉搜索树插入一个节点:新节点肯定能在叶子节点里找到它的位置
- 确定遍历函数返回值:当前遍历的子树的根节点
- 确定遍历函数的出口:当遍历的子树的根节点为空,意思是说找到了新节点的位置!!!!!返回值是新的节点newnode,表示当前遍历的子树的左(右)子树是newnode
- 递归部分1:如果新节点的值小,那就往左递归,返回值为当前root的左子树
- 递归部分2:如果新节点的值大,那就往右递归,返回值为当前root的右子树
规范解答
class Solution:
def insert(self,node,val):#返回node
if node==None:
newnode=TreeNode(val)
return newnode
if val<node.val:
node.left=self.insert(node.left,val)
if val>node.val:
node.right=self.insert(node.right,val)
return node
def insertIntoBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
return self.insert(root,val)
450. 删除二叉搜索树中的节点
题目
给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。
wo shi ben dan
- 这个题目是二叉搜索树,并需要保证删除后的树保持二叉搜索树的性质
- 我的思路是记录要被删除节点的父节点,和记录孩子的方向(比如被删节点是父节点的左孩子还是右孩子)然后进行后序的操作(比如让父节点的左孩子为什么什么)。我的问题是:没有形成递归脑袋!没确定函数的参数和返回值的意义!特别是返回值!返回值返回给上一层,即跟被删节点的父节点联系上了。
solution(看视频写出来的)
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def deleteNode(self, root: Optional[TreeNode], key: int) -> Optional[TreeNode]:
# 出口1.遍历到空节点,返回空给上一层
if root==None:return None
# 出口2.在遍历中找到了目标节点,进行删除逻辑
if root.val==key:
# 1.如果目标节点是叶子节点,删除后向上一层返回空
if root.left==None and root.right==None:return None
# 2.如果目标节点的左孩子不为空,删除当前层的root,向上一层返回左孩子
elif root.left!=None and root.right==None:return root.left
# 3.如果目标节点的右孩子不为空,删除当前层的root,向上一层返回右孩子
elif root.left==None and root.right!=None:return root.right
# 4.如果目标节点的左右孩子子树均存在,则让右子树继位(返回右孩子),把左孩子接在右孩子的最深最左侧节点下保证二叉搜索树的特性
elif root.left!=None and root.right!=None:
cur=root.right
while(cur.left!=None):cur=cur.left
print(cur.val)
cur.left=root.left
return root.right
# 单层递归的逻辑,记得确定方向,因为它是搜索树
if key<root.val:
root.left=self.deleteNode(root.left,key)
elif key>root.val:
root.right=self.deleteNode(root.right,key)
return root