530.二叉搜索树的最小绝对差
501.二叉搜索树中的众数
236. 二叉树的最近公共祖先
235. 二叉搜索树的最近公共祖先
701.二叉搜索树中的插入操作
450.删除二叉搜索树中的节点
669. 修剪二叉搜索树
108.将有序数组转换为二叉搜索树
538.把二叉搜索树转换为累加树
总结篇
530.二叉搜索树的最小绝对差
注意 搜索树:想到中序遍历的从小到大的有序结果
双指针的应用,全局的设定。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public int ans = Integer.MAX_VALUE;
public TreeNode pre_node = null;
public int getMinimumDifference(TreeNode root) {
search(root);
return ans;
}
public void search(TreeNode node){
if(node == null) return;
search(node.left);
if(pre_node != null) ans = Math.min(ans, node.val-pre_node.val);
pre_node = node;
search(node.right);
}
}
501.二叉搜索树中的众数
搜索树:中序遍历的有序数列
和上面那题一样 使用双指针
前后进行对比
注意pre_node的更新位置实在搜索right之前
进行计数以及对比的时候需要设计好变化和对比的先后顺序。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
ArrayList<Integer> ans = new ArrayList<Integer>();
int max_time = 0;
int count = 0;
TreeNode pre_node = null;
public int[] findMode(TreeNode root) {
search(root);
int[] ansList = new int[ans.size()];
for(int i = 0; i < ans.size(); i++){
ansList[i] = ans.get(i);
}
return ansList;
}
public void search(TreeNode node){
if (node == null) return;
search(node.left);
//计数
if (pre_node == null || pre_node.val != node.val){
count = 1;
}
else{
count ++;
}
//更新
if(count == max_time) ans.add(node.val);
if(count > max_time){
ans.clear();
max_time = count;
ans.add(node.val);
}
pre_node = node;
search(node.right);
}
}
236. 二叉树的最近公共祖先
最近公共祖先想到的是回溯的方法,在找到一个后找第二个点,如果左右都有返回响应,则表明这个点就是她们的公共祖先点
递归问题 回溯思想
想终止条件:找到了,或者到头了
探索:左边,右边
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null || root.val == p.val || root.val == q.val) 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) return left;
if(right != null) return right;
return null;
}
}
235. 二叉搜索树的最近公共祖先
因为是搜索数,找到两个点p,q的最近公共祖先就是找[p,q]区间内遇到的第一个点
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root == null) return null;
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;
}
}
701.二叉搜索树中的插入操作
注意考虑头指针就是null的情况
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public TreeNode insertIntoBST(TreeNode root, int val) {
if(root == null) return new TreeNode(val);
search(root, val);
return root;
}
public void search(TreeNode node, int val){
if (node.val > val){
if(node.left == null) {
node.left = new TreeNode(val);
return;
}
search(node.left, val);
}
else{
if(node.right == null){
node.right = new TreeNode(val);
return;
}
search(node.right, val);
}
}
}
可以改写为
class Solution {
public TreeNode insertIntoBST(TreeNode root, int val) {
if (root == null) // 如果当前节点为空,也就意味着val找到了合适的位置,此时创建节点直接返回。
return new TreeNode(val);
if (root.val < val){
root.right = insertIntoBST(root.right, val); // 递归创建右子树
}else if (root.val > val){
root.left = insertIntoBST(root.left, val); // 递归创建左子树
}
return root;
}
}
450.删除二叉搜索树中的节点
我的第一版本编写
注意边界的思考:在做二叉树问题的时候,每一次判断都要思考会不会是null的情况,如果是null应该怎么做,之前是否有过滤掉这个问题
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public TreeNode deleteNode(TreeNode root, int key) {
if(root == null) return null;
if(root.val == key){
root = search(root);
return root;
}
TreeNode temp = root;
boolean flag = false;
while(temp != null){
if(temp.val > key) {
if(temp.left == null){
flag = true;
break;
}
if(temp.left.val == key) break;
temp = temp.left;
}
else {
if(temp.right == null){
flag = true;
break;
}
if(temp.right.val == key) break;
temp = temp.right;
}
}
if (flag || temp == null) return root;
if(temp.left != null && temp.left.val == key) temp.left = search(temp.left);
if(temp.right != null && temp.right.val == key) temp.right = search(temp.right);
return root;
}
public TreeNode search(TreeNode root){
if(root.right == null) return root.left;
if(root.left == null) return root.right;
TreeNode temp = root.right;
while(temp.left != null) temp = temp.left;
temp.left = root.left;
return root.right;
}
}
可以简化为向两边寻找的方式
class Solution {
public TreeNode deleteNode(TreeNode root, int key) {
root = delete(root,key);
return root;
}
private TreeNode delete(TreeNode root, int key) {
if (root == null) return null;
if (root.val > key) {
root.left = delete(root.left,key);
} else if (root.val < key) {
root.right = delete(root.right,key);
} else {
if (root.left == null) return root.right;
if (root.right == null) return root.left;
TreeNode tmp = root.right;
while (tmp.left != null) {
tmp = tmp.left;
}
root.val = tmp.val;
root.right = delete(root.right,tmp.val);
}
return root;
}
}
669. 修剪二叉搜索树
给定一个二叉搜索树,同时给定最小边界L 和最大边界 R。通过修剪二叉搜索树,使得所有节点的值在[L, R]中 (R>=L) 。你可能需要改变树的根节点,所以结果应当返回修剪好的二叉搜索树的新的根节点。
理解了最关键部分了我们再递归三部曲:
- 确定递归函数的参数以及返回值
这里我们为什么需要返回值呢?
因为是要遍历整棵树,做修改,其实不需要返回值也可以,我们也可以完成修剪(其实就是从二叉树中移除节点)的操作。
但是有返回值,更方便,可以通过递归函数的返回值来移除节点。
- 确定终止条件
修剪的操作并不是在终止条件上进行的,所以就是遇到空节点返回就可以了。
- 确定单层递归的逻辑
如果root(当前节点)的元素小于low的数值,那么应该递归右子树,并返回右子树符合条件的头结点
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public TreeNode trimBST(TreeNode root, int low, int high) {
if(root == null) return null;
if(root.val < low){
return trimBST(root.right, low, high);
}
if(root.val > high){
return trimBST(root.left, low, high);
}
root.left = trimBST(root.left, low, high);
root.right = trimBST(root.right, low, high);
return root;
}
}
108.将有序数组转换为二叉搜索树
将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树。
本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。
注意是左右子树的高度差的绝对值不超过1!!!!
所以不能是劈叉那种
这里想 每个的高度差的绝对值不超过1, 形成了重复,可以使用递归进行解决。
中间节点为中间的数字,两边重复形成。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public TreeNode sortedArrayToBST(int[] nums) {
return search(nums, 0, nums.length);
}
public TreeNode search(int[] nums, int left, int right){
if (left >= right) return null;
int mid = left + (right - left)/2;
TreeNode temp = new TreeNode(nums[mid]);
temp.left = search(nums, left, mid);
temp.right = search(nums, mid+1, right);
return temp;
}
}
538.把二叉搜索树转换为累加树
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode() {} * TreeNode(int val) { this.val = val; } * TreeNode(int val, TreeNode left, TreeNode right) { * this.val = val; * this.left = left; * this.right = right; * } * } */ class Solution { int sum = 0; public TreeNode convertBST(TreeNode root) { if (root == null) return null; TreeNode temp = new TreeNode(0); temp.right = convertBST(root.right); sum += root.val; temp.val = sum; temp.left = convertBST(root.left); return temp; } }
二叉树总结篇!!!
非常详细,值得二刷
https://programmercarl.com/二叉树总结篇.html#求二叉树的属性
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能
· 什么是nginx的强缓存和协商缓存
· 一文读懂知识蒸馏