1. 二叉搜索树的最近公共祖先
递归法:
利用二叉搜索树的性质:左子树的所有节点值 < 当前节点值 < 右子树的所有节点值。
通过递归的方式,逐步缩小搜索范围,直到找到一个节点,使得 p
和 q
分别位于该节点的两侧。
具体递归逻辑如下:
目标区间在左子树上
if (root.val > p.val && root.val > q.val) {
return lowestCommonAncestor(root.left, p, q);
}
如果当前节点的值大于 p
和 q
的值,说明 p
和 q
都在当前节点的左子树上。
递归地在左子树上查找最近公共祖先。
目标区间在右子树上
else if (root.val < p.val && root.val < q.val) {
return lowestCommonAncestor(root.right, p, q);
}
如果当前节点的值小于 p
和 q
的值,说明 p
和 q
都在当前节点的右子树上。
递归地在右子树上查找最近公共祖先。
找到最近公共祖先
else return root;
如果当前节点的值既不同时大于 p
和 q
,也不同时小于 p
和 q
,那么当前节点就是 p
和 q
的最近公共祖先。
这是因为在二叉搜索树中,当 p
和 q
分别位于当前节点的两侧时,当前节点就是它们的最低公共祖先。
//当我们从上向下去递归遍历,第一次遇到 cur节点是数值在[q, p]区间中,那么cur就是 q和p的最近公共祖先。
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);
}else if(root.val
迭代法:
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
while(true){
if(root.val>p.val&&root.val>q.val){
root=root.left;
}else if(root.val
2. 二叉搜索树中的插入操作
递归法:
遍历二叉搜索树,找到空节点插入元素
1.确定递归函数参数以及返回值
参数就是根节点指针,以及要插入元素,返回类型为节点类型TreeNode
2.确定终止条件
终止条件就是找到遍历的节点为null的时候,就是要插入节点的位置了,并把插入的节点返回。
3.确定单层递归的逻辑
因为这是搜索树,搜索树是有方向的,可以根据插入元素的数值,决定递归方向。
如遍历节点值大于插入值,说明目标插入位置在左子树上
如遍历节点值小于插入值,说明目标插入位置在右子树上
class Solution {
public TreeNode insertIntoBST(TreeNode root, int val) {
if(root==null){
TreeNode node=new TreeNode(val);
return node;
}
if(root.val>val) root.left=insertIntoBST(root.left,val);
if(root.val
迭代法:
如果树为空,直接创建一个新节点并返回。
遍历树以找到新值应该插入的位置。
在合适的位置插入新节点。
返回原始的根节点
class Solution {
public TreeNode insertIntoBST(TreeNode root, int val) {
if(root==null){
TreeNode node=new TreeNode(val);
return node;
}
if(root.val>val) root.left=insertIntoBST(root.left,val);
if(root.val
3. 删除二叉搜索树中的节点
递归法:
利用二叉搜索树的性质(左子树 < 当前节点 < 右子树)来定位目标节点。
在二叉搜索树中,删除一个节点需要考虑以下几种情况:
1.被删除节点是叶子节点:直接删除即可。
2.被删除节点只有一个子节点:删除该节点,并用其子节点替换它。
3.被删除节点有两个子节点:找到右子树中的最小值节点(即右子树中最左边的节点),将当前节点的左子树接到右子树的最小值节点的左子树上得到新右子树。最后用新右子树替换当前节点。
class Solution {
public TreeNode deleteNode(TreeNode root, int key) {
if(root==null) return null;
while(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;
return root.right;
}
}
if(root.val>key) root.left=deleteNode(root.left,key);
if(root.val