235.二叉搜索树的最近公共祖先
题目链接:235. 二叉搜索树的最近公共祖先 - 力扣(LeetCode)
解题思路:
这个写法根本没用到二叉搜索树这个性质,是个树就可以这么写
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { // 返回的值是最小的公共节点或者p和q
// 首先想要找到最近的公共祖先,就一定得自底向上,那么就需要后序遍历 左右中
if(root == p || root == q || root == null) return root;
TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);
if(left != null && right != null){
return root;
}
if(left != null && right == null) return left;
else if(left == null && right != null) return right;
else return null;
}
}
利用了二叉搜索树的性质:层序遍历,第一个满足val在p和q的val之间的树节点就是最小的公共节点
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { // 返回的值是最小的公共节点或者p和q
// 层序遍历,第一个夹在两种中间的就是最近公共祖先
Queue<TreeNode> que = new LinkedList<>();
que.offer(root);
while(!que.isEmpty()){
TreeNode cur = que.poll();
if(((cur.val - p.val) <= 0 && (cur.val - q.val) >= 0)
|| ((cur.val - p.val) >= 0 && (cur.val - q.val) <= 0)){
return cur;
}
if(cur.left != null) que.offer(cur.left);
if(cur.right != null) que.offer(cur.right);
}
return null;
}
}
701.二叉搜索树中的插入操作
题目链接:701. 二叉搜索树中的插入操作 - 力扣(LeetCode)
解题思路:
只是实现了最简单的一种,直接去树里面找他的位置
class Solution {
public TreeNode insertIntoBST(TreeNode root, int val) {
TreeNode node = new TreeNode(val);
if(root == null) return node;
TreeNode cur = root;
while(cur.left != null || cur.right != null){
if(cur.val < val && cur.right != null){
cur = cur.right;
}else if(cur.val > val && cur.left != null){
cur = cur.left;
}else{
break;
}
}
if(cur.val < val){
cur.right = node;
}
else{
cur.left = node;
}
return root;
}
}
450.删除二叉搜索树中的节点
题目链接:450. 删除二叉搜索树中的节点 - 力扣(LeetCode)
解题思路:
就是进行了一个模拟
1.首先是判断树里是否有要删除的结点
2.有的话判断是否有左右孩子,根据有没有左右孩子分类进行处理
最复杂的就是左右孩子都有的情况,可以让右孩子顶替要删除结点的位置,然后将要删除结点的左孩子当作要删除结点右孩子中最左侧的结点,也就是右孩子中最小值结点的左孩子。
就是如果要删除结点是root的话需要单独处理,比较麻烦,方法有待改进。
class Solution {
public TreeNode deleteNode(TreeNode root, int key) {
// 将这个题分为两步,第一步找到要删除节点位置,第二步,重构树
if(root == null) return null;
if(root.val == key){
if(root.left == null && root.right == null) return null;
else if(root.left == null && root.right != null) return root.right;
else if(root.right == null && root.left != null) return root.left;
else{
TreeNode p = root.right;
while(p.left != null){
p = p.left;
}
p.left = root.left;
return root.right;
}
}
// 1.找出要删除节点的位置
TreeNode cur = root;
TreeNode pre = root;
int flag = -1; //为0代表当前节点为父节点的左孩子,1代表右孩子
while(cur.val != key){
if(cur.val < key && cur.right != null){
if(cur.right.val == key){
pre = cur;
flag = 1;
}
cur = cur.right;
}else if(cur.val > key && cur.left != null){
if(cur.left.val == key){
pre = cur;
flag = 0;
}
cur = cur.left;
}else{
break;
}
}
// 没有value为key的节点
if(cur.val != key) return root;
// 找到了 cur就是要删除的节点,将cur.left接到cur.right的最小的节点上 cur.right最小的节点就是一直往左走知道为空
if(cur.left == null && cur.right == null){//叶子节点,左右孩子都不存在
if(flag == 1) pre.right = null;
else if(flag == 0) pre.left = null;
return root;
}
else if(cur.left == null && cur.right != null){
if(flag == 1) pre.right = cur.right;
else if(flag == 0) pre.left = cur.right;
return root;
}
else if(cur.left != null && cur.right == null){
if(flag == 1) pre.right = cur.left;
else if(flag == 0) pre.left = cur.left;
return root;
}
// 左右都不为空
TreeNode q = cur.right;
if(flag == 1) pre.right = q;
else if(flag == 0) pre.left = q;
while(q.left != null){
q = q.left;
}
q.left = cur.left;
return root;
}
}