算法训练Day 22

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
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值