算法训练营(day22)
235. 二叉搜索树的最近公共祖先
题目链接:https://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-search-tree/description/
给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
解题思路
解题过程:
思路一:递归
- 二叉搜索树的最近公共祖先比二叉树的最近工作祖先要好求
- 因为二叉搜索树自带顺序,所以可以直接比较大小进行节点返回
思路二:迭代
详细代码
解法一:递归
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
class Solution { public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { if(root.val > p.val && root.val > q.val){ return lowestCommonAncestor(root.left, p, q); } if(root.val < p.val && root.val < q.val){ return lowestCommonAncestor(root.right, p, q); } return root; } }
|
解法二:迭代
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
class Solution { public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { while(root != null){ if(root.val > q.val && root.val > p.val){ root = root.left; }else if(root.val < q.val && root.val < p.val){ root = root.right; }else { break; } } return root; } }
|
701. 二叉搜索树中的插入操作
题目链接:https://leetcode.cn/problems/insert-into-a-binary-search-tree/description/
给定二叉搜索树(BST)的根节点 root
和要插入树中的值 value
,将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据 保证 ,新值和原始二叉搜索树中的任意节点值都不同。
注意,可能存在多种有效的插入方式,只要树在插入后仍保持为二叉搜索树即可。 你可以返回 任意有效的结果 。
解题思路
解题过程:不考虑多种方式,单纯考虑保持二叉搜索树顺序即可
解法一:递归
- 判断插入值与节点值的大小
- 一直遍历到有空节点的地方,将新值插入
解法二:迭代(双指针)
- 判断插入值与节点值的大小
- 遍历到叶子节点,判断叶子节点和插入值的大小
- 叶子节点 > 插入值,插入值放在叶子节点的 左子树
- 叶子节点 < 插入值,插入值放在叶子节点的 右子树
详细代码
解法一:递归
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
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); } if(root.val < val){ root.right = insertIntoBST(root.right, val); } return root; } }
|
解法二:迭代
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
|
class Solution { public TreeNode insertIntoBST(TreeNode root, int val) { if(root == null){ return new TreeNode(val); } TreeNode newRoot = root; TreeNode pre = root; while(root != null){ pre = root; if(root.val > val){ root = root.left; }else if(root.val < val){ root = root.right; } }
if(pre.val > val){ pre.left = new TreeNode(val); }else { pre.right = new TreeNode(val); }
return newRoot; } }
|
450. 删除二叉搜索树中的节点
题目链接:https://leetcode.cn/problems/delete-node-in-a-bst/description/
给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。
一般来说,删除节点可分为两个步骤:
- 首先找到需要删除的节点;
- 如果找到了,删除它。
解题思路
解题过程:
本题需要考虑删除节点的五种情况:
- 第一种情况:没找到删除的节点,遍历到空节点直接返回了
- 第二种情况:左右孩子都为空(叶子节点),直接删除节点, 返回NULL为根节点
- 第三种情况:删除节点的左孩子为空,右孩子不为空,删除节点,右孩子补位,返回右孩子为根节点
- 第四种情况:删除节点的右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子为根节点
- 第五种情况:左右孩子节点都不为空,则将删除节点的左子树头结点(左孩子)放到删除节点的右子树的最左面节点的左孩子上,返回删除节点右孩子为新的根节点。
详细代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
|
class Solution { public TreeNode deleteNode(TreeNode root, int key) { if(root == null){ return root; } if(root.val == key){ if(root.left == null){ return root.right; }else if(root.right == null){ return root.left; }else { TreeNode cur = root.right; while(cur.left != null){ cur = cur.left; } cur.left = root.left; root = root.right; return root; } } if(root.val > key){ root.left = deleteNode(root.left, key); } if(root.val < key){ root.right = deleteNode(root.right, key); } return root; } }
|