文章目录
- 题目
- 标题和出处
- 难度
- 题目描述
- 要求
- 示例
- 数据范围
- 解法一
- 思路和算法
- 代码
- 复杂度分析
- 解法二
- 思路和算法
- 代码
- 复杂度分析
题目
标题和出处
标题:二叉搜索树中的插入操作
出处:701. 二叉搜索树中的插入操作
难度
3 级
题目描述
要求
给定二叉搜索树的根结点 root \texttt{root} root 和要插入树中的值 val \texttt{val} val,返回插入操作后的二叉搜索树的根结点。保证新值和原始二叉搜索树中的任意结点值都不同。
注意,可能存在多种有效的插入方式,只要树在插入后仍保持为二叉搜索树即可。可以返回任意有效的结果。
示例
示例 1:
输入: root = [4,2,7,1,3], val = 5 \texttt{root = [4,2,7,1,3], val = 5} root = [4,2,7,1,3], val = 5
输出: [4,2,7,1,3,5] \texttt{[4,2,7,1,3,5]} [4,2,7,1,3,5]
解释:另一个满足题目要求可以通过的树是:
示例 2:
输入: root = [40,20,60,10,30,50,70], val = 25 \texttt{root = [40,20,60,10,30,50,70], val = 25} root = [40,20,60,10,30,50,70], val = 25
输出: [40,20,60,10,30,50,70,null,null,25] \texttt{[40,20,60,10,30,50,70,null,null,25]} [40,20,60,10,30,50,70,null,null,25]
示例 3:
输入: root = [4,2,7,1,3,null,null,null,null,null,null], val = 5 \texttt{root = [4,2,7,1,3,null,null,null,null,null,null], val = 5} root = [4,2,7,1,3,null,null,null,null,null,null], val = 5
输出: [4,2,7,1,3,5] \texttt{[4,2,7,1,3,5]} [4,2,7,1,3,5]
数据范围
- 树中结点数目在范围 [0, 10 4 ] \texttt{[0, 10}^\texttt{4}\texttt{]} [0, 104] 内
- -10 8 ≤ Node.val ≤ 10 8 \texttt{-10}^\texttt{8} \le \texttt{Node.val} \le \texttt{10}^\texttt{8} -108≤Node.val≤108
- 所有值 Node.val \texttt{Node.val} Node.val 各不相同
- -10 8 ≤ val ≤ 10 8 \texttt{-10}^\texttt{8} \le \texttt{val} \le \texttt{10}^\texttt{8} -108≤val≤108
- 保证 val \texttt{val} val 在原始二叉搜索树中不存在
解法一
思路和算法
如果二叉搜索树为空,则插入结点之后,二叉搜索树中只有插入的结点,返回该结点即可。如果二叉搜索树不为空,为了在插入操作之后维持二叉搜索树的性质,需要比较根结点值和插入值,决定应该在根结点的哪个子树中插入结点。
-
如果根结点值大于目标值,则应该在根结点的左子树中插入结点。
-
如果根结点值小于目标值,则应该在根结点的右子树中插入结点。
上述过程是一个递归的过程。递归的终止条件是当前结点为空,此时返回插入的结点。对于其余情况,定位到应该插入结点的子树,对该子树调用递归,并用递归调用的结果更新当前结点的相应子树。
代码
class Solution {public TreeNode insertIntoBST(TreeNode root, int val) {if (root == null) {return new TreeNode(val);}if (root.val > val) {root.left = insertIntoBST(root.left, val);} else {root.right = insertIntoBST(root.right, val);}return root;}
}
复杂度分析
-
时间复杂度: O ( n ) O(n) O(n),其中 n n n 是二叉搜索树的结点数。时间复杂度取决于二叉搜索树的高度,最坏情况下二叉搜索树的高度是 O ( n ) O(n) O(n)。
-
空间复杂度: O ( n ) O(n) O(n),其中 n n n 是二叉搜索树的结点数。空间复杂度主要是递归调用的栈空间,取决于二叉搜索树的高度,最坏情况下二叉搜索树的高度是 O ( n ) O(n) O(n)。
解法二
思路和算法
递归实现可以改成迭代实现。如果根结点为空,则返回插入的结点。当根结点不为空时,从根结点开始搜索,定位到插入结点的位置。搜索结束的条件是当前结点为空,此时需要定位到当前结点的父结点才能插入结点,因此在搜索过程中需要维护当前结点的父结点。
每一次搜索时,首先将父结点设为当前结点,然后执行如下操作,直到当前结点为空。
-
如果当前结点值大于目标值,则应该在根结点的左子树中插入结点,因此将当前结点移动到左子结点。
-
如果当前结点值小于目标值,则应该在根结点的右子树中插入结点,因此将当前结点移动到右子结点。
搜索结束时,比较父结点的值和目标值,决定插入的结点应该作为父结点的左子结点或者右子结点。
代码
class Solution {public TreeNode insertIntoBST(TreeNode root, int val) {TreeNode insertNode = new TreeNode(val);if (root == null) {return insertNode;}TreeNode node = root, parent = null;while (node != null) {parent = node;if (node.val > val) {node = node.left;} else {node = node.right;}}if (parent.val > val) {parent.left = insertNode;} else {parent.right = insertNode;}return root;}
}
复杂度分析
-
时间复杂度: O ( n ) O(n) O(n),其中 n n n 是二叉搜索树的结点数。时间复杂度取决于二叉搜索树的高度,最坏情况下二叉搜索树的高度是 O ( n ) O(n) O(n)。
-
空间复杂度: O ( 1 ) O(1) O(1)。