内容:
- 修剪二叉搜索树(669)
- 将有序数组转换为二叉搜索树(108)
- 把二叉搜索树转换为累加树(538)
- 二叉树总结
1. 修剪二叉搜索树
难度:🔥🔥🔥
建议:这道题目比较难,比添加和删除节点难的多,建议先看视频理解
1.1 思路分析
我们使用递归三部曲来解决这道题目
因为我们需要通过返回值来连接树之间的关系,所以函数返回TreeNode
类型。
终止条件为root == null
此时我们返回null
。
接下来是单层递归逻辑:
因为这是一颗二叉搜索树,当当前节点的值小于low
时,我们递归向该节点的右子树去搜索,因为该节点的右子树的数值可能在我们的范围中,我们将修剪后得到的节点返回给root
的左子树。
当当前节点的值大于high
时,我们递归向该节点的左子树去搜索,因为该节点的左子树的数值可能在我们的范围中,我们将修剪后得到的节点返回给root
的右子树。
最后我们返回修剪后的二叉树的根节点
1.2 代码实现
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;
}
}
1.3 注意事项
return trimBST(root.right,low,high)
这句我们可不可写成return root.right
呢?答案是不可以的,因为我们不知道该节点右子树中是否存在小于low
的节点。return trimBST(root.left,low,high)
同理
1.4 收获总结
2. 将有序数组转换为二叉搜索树
难度:🔥🔥
建议:本题简单一些,可以尝试先自己做做
2.1 思路分析
这道题的本质就是寻找分割点,分割点作为当前节点,然后递归左区间和右区间
2.2 代码实现
class Solution {
public TreeNode sortedArrayToBST(int[] nums) {
TreeNode root = traversal(nums,0,nums.length - 1);
return root;
}
private TreeNode traversal(int[] nums,int left,int right){
//给的数组是有序的!!!
if (left > right) {//不合法区间
return null;
}
//每次都取区间的中间数值作为分割点
int mid = (left + right) / 2;
TreeNode root = new TreeNode(nums[mid]);
//我们定义的区间为左闭右闭
root.left = traversal(nums,left,mid - 1);
root.right = traversal(nums,mid + 1,right);
return root;
}
}
2.3 注意事项
2.4 收获总结
与从中序与后序遍历序列构造二叉树和构造一棵最大的二叉树思路相似,以一个节点作为分割点,然后递归处理左区间,右区间。
以及循环不变量在定义区间的使用十分重要。
3. 把二叉搜索树转换为累加树
难度:🔥🔥
建议:本题也不难,在求二叉搜索树的最小绝对差和众数那两道题都讲过了双指针法,思路也是一样的
3.1 思路分析
从树中可以看出累加的顺序是右中左,所以我们需要反中序遍历这个二叉树,然后顺序累加就可以了,同样我们使用两个指针来方便累加
3.2 代码实现
class Solution {
int pre;//用于记录前一个节点的值
public TreeNode convertBST(TreeNode root) {
pre = 0;
traversal(root);
return root;
}
private void traversal(TreeNode root){
if (root == null) {
return;
}
//使用反中序遍历,从大到小
traversal(root.right);
root.val += pre;
pre = root.val;
traversal(root.left);
}
}
3.3 注意事项
3.4 收获总结
4.二叉树总结
来自代码随想录
在二叉树题目选择什么遍历顺序是不少同学头疼的事情,我们做了这么多二叉树的题目了,Carl给大家大体分分类
- 涉及到二叉树的构造,无论普通二叉树还是二叉搜索树一定前序,都是先构造中节点。
- 求普通二叉树的属性,一般是后序,一般要通过递归函数的返回值做计算。
- 求二叉搜索树的属性,一定是中序了,要不白瞎了有序性了。
注意在普通二叉树的属性中,我用的是一般为后序,例如单纯求深度就用前序,二叉树:找所有路径也用了前序,这是为了方便让父节点指向子节点。
所以求普通二叉树的属性还是要具体问题具体分析。