LeetCode 235. 二叉搜索树的最近公共祖先
题目链接:235. 二叉搜索树的最近公共祖先
思路:与昨天的题236. 二叉树的最近公共祖先一致,但此题的二叉树是搜索二叉树,可以通过直接比较p和q的大小来锁定公共祖先的位置。
Python版本:
class Solution:
def lowestCommonAncestor(self, root, p, q):
if root.val > p.val and root.val > q.val:
return self.lowestCommonAncestor(root.left, p, q)
if root.val < p.val and root.val < q.val:
return self.lowestCommonAncestor(root.right, p, q)
return root
时间复杂度: O ( n ) O(n) O(n),空间复杂度: O ( n ) O(n) O(n)
go版本:
func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
return foo(root, p, q)
}
func foo(root, p, q *TreeNode) *TreeNode {
if root == nil {
return root
}
if root.Val > p.Val && root.Val > q.Val {
left := foo(root.Left, p, q)
if left != nil {
return left
}
}
if root.Val < p.Val && root.Val < q.Val {
right := foo(root.Right, p, q)
if right != nil {
return right
}
}
return root
}
LeetCode 701. 二叉搜索树中的插入操作
题目链接:701. 二叉搜索树中的插入操作
思路:因为是二叉搜索树,通过比较节点间大小关系来找到一个合适的空节点位置插入即可。
Python版本:
class Solution:
def insertIntoBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
if not root: return TreeNode(val)
if val < root.val:
root.left = self.insertIntoBST(root.left, val)
if root.val < val:
root.right = self.insertIntoBST(root.right, val)
return root
时间复杂度: O ( n ) O(n) O(n),空间复杂度: O ( n ) O(n) O(n)
go版本:
func insertIntoBST(root *TreeNode, val int) *TreeNode {
if root == nil {
root = &TreeNode{Val: val}
return root
}
if root.Val > val {
root.Left = insertIntoBST(root.Left, val)
} else {
root.Right = insertIntoBST(root.Right, val)
}
return root
}
LeetCode 450. 删除二叉搜索树中的节点
题目链接:450. 删除二叉搜索树中的节点
思路:删除节点要比增加节点复杂的多,增加节点只需要遍历到一个合适的空位置然后插入即可,但删除节点会有以下五种情况需要考虑:
- 第一种情况:没找到删除的节点,遍历到空节点直接返回;
- 第二种情况:左右孩子都为空(叶子节点),直接删除该节点,返回空节点;
- 第三种情况:删除节点的左孩子为空,右孩子不为空,删除节点,右孩子补位,返回右孩子;
- 第四种情况:删除节点的右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子;
- 第五种情况:左右孩子节点都不为空,则将删除节点的左孩子放到删除节点的右子树的最左面节点的左孩子上,返回删除节点的右孩子。
第五种情况也可以这么处理:将删除节点的右孩子放到删除节点的左孩子的最右面节点的右孩子上,然后返回删除节点的左孩子。
Python版本:
class Solution:
def deleteNode(self, root: Optional[TreeNode], key: int) -> Optional[TreeNode]:
if not root :
return None
if root.val < key :
root.right = self.deleteNode(root.right, key)
elif root.val > key :
root.left = self.deleteNode(root.left, key)
else:
if not root.left :
return root.right
if not root.right:
return root.left
node = root.right
while node.left :
node = node.left
node.left = root.left
root = root.right
return root
时间复杂度: O ( n ) O(n) O(n),空间复杂度: O ( n ) O(n) O(n)
go版本:
func deleteNode(root *TreeNode, key int) *TreeNode {
if root==nil {
return nil
}
if key<root.Val {
root.Left = deleteNode(root.Left,key)
return root
}
if key>root.Val {
root.Right = deleteNode(root.Right,key)
return root
}
if root.Right == nil {
return root.Left
}
if root.Left == nil {
return root.Right
}
node:=root.Right
for node.Left != nil {
node = node.Left
}
root.Val = node.Val
root.Right = deleteNode1(root.Right)
return root
}
func deleteNode1(root *TreeNode) *TreeNode {
if root.Left==nil {
pRight := root.Right
root.Right = nil
return pRight
}
root.Left = deleteNode1(root.Left)
return root
}