算法训练Day22|235. 二叉搜索树的最近公共祖先 ● 701.二叉搜索树中的插入操作 ● 450.删除二叉搜索树中的节点

简介: 算法训练Day22|235. 二叉搜索树的最近公共祖先 ● 701.二叉搜索树中的插入操作 ● 450.删除二叉搜索树中的节点

LeetCode:235. 二叉搜索树的最近公共祖先

235. 二叉搜索树的最近公共祖先 - 力扣(LeetCode)

1. 思路

利用二叉搜索树的特性,当root.val介于p.val和q.val时,即可返回root节点。

2. 代码实现

 1class Solution {
 2    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
 3        // root介于p和q之间时进行返回即可
 4
 5       if (root.val > p.val && root.val > q.val) { // root 在p\q的右侧,向左遍历
 6           return lowestCommonAncestor(root.left, p, q);
 7       } 
 8       if (root.val < p.val && root.val < q.val) { // root 在p\q的左侧,向右遍历
 9           return lowestCommonAncestor(root.right, p, q);
10       }
11       return root; // 找到了结果
12    }

3. 复杂度分析

时间复杂度:O(n).最坏情况下为链表。

空间复杂度:O(n).最坏情况下是链表,则调用n层递归函数,栈的开销也一致。


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

701. 二叉搜索树中的插入操作 - 力扣(LeetCode)


1. 思路

利用二叉搜索树的特性,遇到空节点即可将该值val创建新节点并加入到树中。前序遍历~


2. 代码实现

 1class Solution {
 2    // 确定递归函数的参数及返回值
 3    public TreeNode insertIntoBST(TreeNode root, int val) {
 4        // 遇到空节点将该值加入其中并返回(确定递归函数的终止条件)
 5        if (root == null) {
 6            TreeNode node = new TreeNode(val);
 7            return node;
 8        }
 9
10        if (val < root.val) {
11            root.left = insertIntoBST(root.left, val);
12        } else if (val > root.val) {
13            root.right = insertIntoBST(root.right, val);
14        } 
15        return root;
16    }
17}

3. 复杂度分析

时间复杂度:O(1)

空间复杂度:O(1)


450.删除二叉搜索树中的节点

450. 删除二叉搜索树中的节点 - 力扣(LeetCode)


1. 思路

递归三部曲

是否有相等值,没有直接返回null,有则进行递归遍历判断,再判断该节点是否有左右子树的情况,当左右子树均不为空时,将该节点的左子树挂到右子树的左子节点上。


2. 代码实现

 1class Solution {
 2    public TreeNode deleteNode(TreeNode root, int key) {
 3        if (root == null) { // 如果根节点为空,直接返回null
 4            return null;
 5        }
 6        if (root.val > key) { // 如果根节点的值大于目标值,递归删除左子树中的目标节点
 7            root.left = deleteNode(root.left, key);
 8            return root;
 9        }
10        if (root.val < key) { // 如果根节点的值小于目标值,递归删除右子树中的目标节点
11            root.right = deleteNode(root.right, key);
12            return root;
13        }
14        if (root.val == key) { // 如果根节点的值等于目标值
15            if (root.left == null && root.right == null) { // 如果根节点没有左右子树,直接返回null
16                return null;
17            }
18            if (root.right == null) { // 如果根节点只有左子树,返回左子树
19                return root.left;
20            }
21            if (root.left == null) { // 如果根节点只有右子树,返回右子树
22                return root.right;
23            }
24            TreeNode successor = root.right; // 找到根节点的后继节点
25            while (successor.left != null) { // 后继节点是右子树中最左边的节点
26                successor = successor.left;
27            }
28            root.right = deleteNode(root.right, successor.val); // 递归删除右子树中的后继节点
29            successor.right = root.right; // 将根节点的右子树赋值给后继节点的右子树
30            successor.left = root.left; // 将根节点的左子树赋值给后继节点的左子树
31            return successor;
32        }
33        return root;
34    }
35}

3. 复杂度分析

时间复杂度:O(n).

空间复杂度:O(n).做坏的情况时链表,递归深度为n层递归函数,栈的空间消耗也为O(n).

相关文章
|
29天前
|
算法
【优选算法专栏】专题九:链表--------两两交换链表中的节点
【优选算法专栏】专题九:链表--------两两交换链表中的节点
17 0
|
2月前
|
NoSQL 算法 安全
Redlock 算法-主从redis分布式锁主节点宕机锁丢失的问题
Redlock 算法-主从redis分布式锁主节点宕机锁丢失的问题
159 0
|
2月前
|
算法 Java
算法:Java计算二叉树从根节点到叶子结点的最大路径和
算法:Java计算二叉树从根节点到叶子结点的最大路径和
|
5月前
|
算法 vr&ar 图形学
☆打卡算法☆LeetCode 222. 完全二叉树的节点个数 算法解析
☆打卡算法☆LeetCode 222. 完全二叉树的节点个数 算法解析
|
4月前
|
存储 JavaScript 算法
TypeScript算法专题 - blog4 - 单链表节点的两-两翻转(两两一组逆序)
TypeScript算法专题 - blog4 - 单链表节点的两-两翻转(两两一组逆序)
29 0
|
4月前
|
JavaScript 算法 C语言
TypeScript算法专题 - blog5 - 单链表节点的`任意k个分组反转`的实现
TypeScript算法专题 - blog5 - 单链表节点的`任意k个分组反转`的实现
24 1
|
4月前
|
JavaScript 算法 前端开发
TypeScript算法专题 - blog2 - 单链表节点的索引、结点删除与链表反转
TypeScript算法专题 - blog2 - 单链表节点的索引、结点删除与链表反转
31 0
|
4月前
|
存储 算法
算法题解-二叉搜索树中第K小的元素
算法题解-二叉搜索树中第K小的元素
|
4月前
|
存储 算法
算法题解-完全二叉树的节点个数
算法题解-完全二叉树的节点个数
|
4月前
|
算法 前端开发
前端算法-将有序数组转换为二叉搜索树
前端算法-将有序数组转换为二叉搜索树