代码训练营 | Day 22 二叉树 08

1、

235. Lowest Common Ancestor of a Binary Search Tree

所以当我们从上向下去递归遍历,第一次遇到 cur节点是数值在[q, p]区间中,那么cur就是 q和p的最近公共祖先。

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def lowestCommonAncestor(self, root, p, q):
        """
        :type root: TreeNode
        :type p: TreeNode
        :type q: TreeNode
        :rtype: TreeNode
        """
        ## 还是要写个另外的def traversal
        return self.traversal(root, p, q)
        # 都要+self,why???
    
    def traversal(self, root, p, q):
        if root is None:
            return root
        ## 中: 没有处理逻辑
        ## 左
        if root.val > p.val and root.val > q.val:
            left = self.traversal(root.left, p, q)
            if left is not None: # if is not None
                return left
        ## 右
        if root.val < p.val and root.val < q.val:
            right = self.traversal(root.right, p, q)
            if right is not None:
                return right
        
        return root # 记得返回值

2、

701. Insert into a Binary Search Tree

实际上是在最下的叶子节点里插入,此时为空的话,所以这里的终止条件是TreeNode == NULL

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def insertIntoBST(self, root, val):
        """
        :type root: TreeNode
        :type val: int
        :rtype: TreeNode
        """
        self.parent = TreeNode(0)
        if root is None:
            return TreeNode(val)
        # 为啥最后返回是root
        self.traversal(root, val)
        
        return root 
        
    def traversal(self, cur, val):
        if cur is None:
            # 这里不是return 空了,因为这里是遍历到最下面的叶子节点,反而是在这里进行逻辑处理
            node = TreeNode(val)
            if val > self.parent.val:
                self.parent.right = node
            else:
                self.parent.left = node

            return

        self.parent = cur 
        # 左
        if cur.val > val:

            self.traversal(cur.left, val)
        # 中
        ##if left.val < val and right.val > val:
            # 处理插入逻辑
        ##    root.val = val

        # 右
        if cur.val < val:
            self.traversal(cur.right, val)
            #self.traversal(root.right)
        

3、

450. Delete Node in a BST

分5种情况:

1)左右为空 - 子节点

2)左为空,右不为空

3)右为空,左不为空

4)左右都不为空

5)没找到要删除的节点

最diffcult的情况是:左右都不为空 --> 

4.1 则将删除节点的左子树放到删除节点的右子树的最左面节点的左孩子的位置

意思是先要把左边移到右边
4.2 并返回删除节点右孩子为新的根节点。

再把当前这个节点删除

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def deleteNode(self, root, key):
        """
        :type root: TreeNode
        :type key: int
        :rtype: TreeNode
        """
        # 情况1 没找到节点
        if root is None:
            return root
        
        # 情况2 找到了
        if root.val == key:
            if root.left is None and root.right is None:
                return None #为啥这里是None,上面是root呢
            elif root.left is None:
                return root.right
            elif root.right is None:
                return root.left
            # 情况5 左不为空右不为空
            else:
                #TreeNode(cur) = root.right
                cur = root.right
                while cur.left is not None:
                    cur = cur.left
                    # 5.1 把左边底下移到右边来
                cur.left = root.left
                return root.right # why?
        #最后是BST单层搜索递归的逻辑
        if (root.val > key):
            root.left = self.deleteNode(root.left, key) #记得这里要 + self.
        if (root.val < key):
            root.right = self.deleteNode(root.right, key)
        return root  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值