2022跟着leedcode学数据结构--第21天

82 阅读2分钟

「这是我参与2022首次更文挑战的第21天,活动详情查看:2022首次更文挑战

image.png

[删除二叉搜索树中的节点]

给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。

一般来说,删除节点可分为两个步骤:

首先找到需要删除的节点; 如果找到了,删除它。  

示例 1:

image.png

输入:root = [5,3,6,2,4,null,7], key = 3 输出:[5,4,6,2,null,null,7] 解释:给定需要删除的节点值是 3,所以我们首先找到 3 这个节点,然后删除它。 一个正确的答案是 [5,4,6,2,null,null,7], 如下图所示。 另一个正确答案是 [5,2,6,null,4,null,7]。

示例 2:

image.png

输入: root = [5,3,6,2,4,null,7], key = 0 输出: [5,3,6,2,4,null,7] 解释: 二叉树不包含值为 0 的节点 示例 3:

输入: root = [], key = 0 输出: []  

提示:

节点数的范围 [0, 104]. -105 <= Node.val <= 105 节点值唯一 root 是合法的二叉搜索树 -105 <= key <= 105  

进阶: 要求算法时间复杂度为 O(h),h 为树的高度。

解题思路:

  • 对于上面的问题还是同样的思路,深度遍历,遍历每一个节点
  • 判断当前节点是否和key值一致,一致则替换,如果有右子节点则进行替换,将右子节点替换为当前节点
  • 递归判断当前数据。
# 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]:
        if not root:
            return root
        if root.val<key:
            root.right = self.deleteNode(root.right, key)
        elif root.val == key:
            root = self.helper(root)
        elif root.val > key :
            root.left = self.deleteNode(root.left, key)
        return root
    
    def helper(self,root):
        if not root.left and not root.right:
            return None
        elif root.right and not root.left:
            root = root.right
        elif root.left and not root.right:
            root = root.left
        elif root.left and root.right:
            cur = root.right
            while cur.left:
                cur = cur.left
            cur.left = root.left
            root = root.right
        return root

执行结果:

image.png

[二叉搜索树中第K小的元素]

给定一个二叉搜索树的根节点 root ,和一个整数 k ,请你设计一个算法查找其中第 k 个最小元素(从 1 开始计数)。

 

示例 1:

image.png

输入:root = [3,1,4,null,2], k = 1 输出:1 示例 2:

image.png

输入:root = [5,3,6,2,4,null,null,1], k = 3 输出:3  

 

提示:

树中的节点数为 n 。 1 <= k <= n <= 104 0 <= Node.val <= 104  

进阶:如果二叉搜索树经常被修改(插入/删除操作)并且你需要频繁地查找第 k 小的值,你将如何优化算法?

解题思路:

  • 根据二叉搜索树的特性 左子树小于当前节点小于右子树
  • 使用中序遍历的方法 将树遍历到res中,其中k-1就是第k个数据
# 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 kthSmallest(self, root: Optional[TreeNode], k: int) -> int:
        res = []
        self.dfs(root, res)
        return res[k-1]

    def dfs(self, node, res):
        if node is None:
            return 
        self.dfs(node.left, res)
        res.append(node.val)
        self.dfs(node.right, res)

执行结果:

image.png