目录
一、力扣669.修剪二叉搜索树
1.1 题目
1.2 思路
本题递归代码分三个模块来写:
(1)递归终止条件:null节点
(2)该节点为要删除节点的处理逻辑:继续向左或者向右递归,将有效的节点返回给上层节点
(3)该节点为不需要删除节点的处理逻辑:继续向左和又递归,将有效的节点返回给本节点作为左右孩子
1.3 代码
class Solution {
public TreeNode trimBST(TreeNode root, int low, int high) {
//判断特殊情况
if(root == null){
return null;
}
return traversal(root,low,high);
}
//递归
public TreeNode traversal(TreeNode root,int low,int high){
//递归终止条件
if(root == null){
return null;
}
//如果当前节点是需要被删除的节点
if(root.val < low){
return traversal(root.right,low,high);
}
if(root.val > high){
return traversal(root.left,low,high);
}
//如果该节点符合条件,不需要被删除
root.left = traversal(root.left,low,high);
root.right = traversal(root.right,low,high);
return root;
}
}
二、力扣108.将有序数组转换为二叉搜索树
2.1 题目
2.2 思路
注意是平衡二叉搜索树;
选取二叉树的中间节点(数组的中间数),根据数组的左右区间来构造二叉树的左右子树。
2.3 代码
lass Solution {
public TreeNode sortedArrayToBST(int[] nums) {
if(nums.length == 0){
return null;
}
return traversal(nums,0,nums.length-1);
}
//递归,划分区间构造左右子树(坚持区间左闭右闭原则)
public TreeNode traversal(int[] nums,int left,int right){
//递归终止条件
if(left > right){
return null;
}
int mid = left +((right-left)>>1);//注意使用移位运算符要加括号
TreeNode root = new TreeNode(nums[mid]);
root.left = traversal(nums,left,mid-1);
root.right = traversal(nums,mid+1,right);
return root;
}
}
2.4 总结
构造二叉树:有序数组选取中间节点,然后递归划分左右区间构造左右子树。
注意使用移位运算符要加括号。
三、力扣538.把二叉搜索树转换为累加树
3.1 题目
3.2 思路
我的思路:先将二叉树中序遍历一遍,将值记录再数组中;
第二次中序遍历时直接累加赋值(设置一个起始索引,置为0,每遍历一个节点就起始索引加一,直到遍历结束)
代码随想录:右中左
3.3 代码
我的思路:(跑出来是错的)
class Solution {
public List<Integer> res = new ArrayList<>();
public int quitIndex = -1;
public TreeNode convertBST(TreeNode root) {
if(root == null){
return null;
}
//第一次中序遍历,从小到大拿到所有节点的值
traversal(root);
//第二次遍历,为节点重新赋值
int sum = 0;
for(int i =0;i<res.size();i++){
sum += res.get(i);
}
traversal2(root,sum);
return root;
}
public void traversal(TreeNode root){
if(root == null){
return;
}
//左中右
traversal(root.left);
res.add(root.val);
traversal(root.right);
}
public void traversal2(TreeNode root,int sum){
if(root == null){
return;
}
//左中右
traversal2(root.left,sum);
if(quitIndex != -1){
sum -= res.get(quitIndex);
root.val = sum;
quitIndex++;
}else{
root.val = sum;
quitIndex++;
}
traversal2(root.right,sum);
}
}
右中左(相当于从大到小遍历):
class Solution {
public int beforeSum = 0;
public TreeNode convertBST(TreeNode root) {
//右中左递归遍历(按值从大到小)
if(root == null){
return null;
}
traversal(root);
return root;
}
public void traversal(TreeNode root){
if(root == null){
return;
}
traversal(root.right);
//中:更新本节点的值
beforeSum += root.val;
root.val = beforeSum;
traversal(root.left);
}
}
3.4 总结
还是要利用好二叉搜索树的有序特性!
二叉树总结参考代码随想录:https://programmercarl.com/%E4%BA%8C%E5%8F%89%E6%A0%91%E6%80%BB%E7%BB%93%E7%AF%87.html#%E6%9C%80%E5%90%8E%E6%80%BB%E7%BB%93