LeetCode 701. 二叉搜索树中的插入操作 | Python

701. 二叉搜索树中的插入操作


题目来源:力扣(LeetCode)https://leetcode-cn.com/problems/insert-into-a-binary-search-tree

题目


给定二叉搜索树(BST)的根节点和要插入树中的值,将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据保证,新值和原始二叉搜索树中的任意节点值都不同。

注意,可能存在多种有效的插入方式,只要树在插入后仍保持为二叉搜索树即可。 你可以返回任意有效的结果。

例如,

给定二叉搜索树:

    4
   / \
  2   7
 / \
1   3

和 插入的值: 5

你可以返回这个二叉搜索树:

     4
   /   \
  2     7
 / \   /
1   3 5

或者这个树也是有效的:

     5
   /   \
  2     7
 / \   
1   3
     \
      4

提示:

  • 给定的树上的节点数介于010^4 之间
  • 每个节点都有一个唯一整数值,取值范围从 010^8
  • -10^8 <= val <= 10^8
  • 新值和原始二叉搜索树中的任意节点值都不同

解题思路


思路:递归、迭代

本站中的 700. 二叉搜索树中的搜索 这道题是希望能够在二叉搜索树上查找指定节点。有兴趣的话,可以尝试下。

而本题,是希望在二叉搜索树上插入指定的节点。

先看看题目中给出的提示:

  • 待插入树中的新值,与原始二叉搜索树的任意节点值都不同,也即是可以不用考虑值相等的情况;
  • 插入方式有多种,只要符合插入节点后仍为二叉搜索树,那么可返回任意一种有效的结果(本篇主要采用的是示例中的第一种插入形式);
  • 给定的树节点数介于 010^4 之间,那么有可能存在空树的情况。

现在,我们先说下二叉搜索树(BST)的定义(可能读者已经都知道了,我这里为了文章的完整性,就再赘述一遍):

  • 结点左子树中所含结点的值小于等于当前结点的值
  • 结点右子树中所含结点的值大于等于当前结点的值
  • 左子树和右子树都是二叉搜索树

那么根据二叉搜索树(BST)的定义,我们可以发现这里只要比较 待插入树中的值 和根节点的值,就能够有效的缩小范围。

在这里,我们可以使用递归或迭代的方法来实现。

递归

这里先看使用递归的具体方法:

  • 当根节点为空时,直接新建树节点作为根节点返回;
  • 当根节点不为空时,需要比较 root 的节点值与给定待插入树中的值 val:
    • 如果 root.val > val,那么 val 应该插入 root 的左子树中,那么此时应该往左子树方向找插入位置;
    • 如果 root.val < val,那么 val 应该插入 root 的右子树中,那么此时应该往右子树方向查找插入位置。

具体的代码实现如下。

# 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 insertIntoBST(self, root: TreeNode, val: int) -> TreeNode:
        node = TreeNode(val)
        
        def dfs(root, val):
            # 当根节点不存在时,返回新建树节点
            if not root:
                return node
            # 如果 root.val < val,说明 val 应该插入 root 的右子树,往 root 的右子树方向继续找位置
            if root.val < val:
                root.right = dfs(root.right, val)
            # 否则 val 应该插入左子树,往 root 的左子树方向继续查找位置
            else:
                root.left = dfs(root.left, val)
            
            return root
        
        return dfs(root, val)

迭代

我们也可以使用迭代的方法,同样是比对 root 的节点值与待插入树中的值,缩小范围。具体做法如下:

  • 当根节点为空时,返回新建树节点;
  • 当根节点不为空时,首先定义变量 cur,指向 root(这里 cur 用于后面迭代更换指向,不至于影响 root)
    • 当 cur.val > val 时,则说明 val 应该插入 cur 的左子树中。此时需要判断 cur.left 是否为空,若为空,将新建树节点插入此处,跳出循环,返回 root;否则令 cur = cur.left,往左子树方向继续查找;
    • 当 cur.val < val 时,则说明 val 应该插入 cur 的右子树中。此时需要判断 cur.right 是否为空,若为空,将新建树节点插入此处,跳出循环,返回 root;否则令 cur = cur.right,往右子树方向继续查找。

具体的代码实现如下:

# 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 insertIntoBST(self, root: TreeNode, val: int) -> TreeNode:
        node = TreeNode(val)
		
        # 根节点为空,直接将新建树节点返回
        if not root:
            return node
        # 定义变量 cur 指向 root
        cur = root
		
        # 循环遍历开始
        while True:
            # 当 cur.val > val,说明 val 应该在 cur 的左子树插入
            if cur.val > val:
                # 如果 cur 左子树为空,将新建树节点插入此处,跳出循环
                if not cur.left:
                    cur.left = node
                    break
                # 否则往左子树方向继续查找
                cur = cur.left
            # cur.val < val,说明 val 应该在 cur 的右子树插入
            else:
                # cur 右子树为空,将新建树节点插入此处,跳出循环
                if not cur.right:
                    cur.right = node
                    break
                # 否则继续往右子树的方向查找
                cur = cur.right

        return root

欢迎关注


公众号 【书所集录】


如有错误,烦请指出,欢迎指点交流。

你可能感兴趣的:(LeetCode,python,算法,二叉搜索树,二叉搜索树中的插入操作)