669.修剪二叉搜索树
调用递归实现剪枝
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); //如果当前节点的值小于low,意味着当前节点及其左子树中的所有节点都小于low,不符合要求。这时,应该跳过当前节点和左子树,递归处理右子树if(root.val > high) return trimBST(root.left, low, high); //同理root.left = trimBST(root.left, low, high); //修剪的目的是删除不在[low, high]范围内的节点 当某个节点不在范围内时,我们选择跳过该节点,并根据其值选择保留左子树或右子树。root.right = trimBST(root.right, low, high); return root;}
}
1. 当前节点值小于 low
if(root.val < low) return trimBST(root.right, low, high);
- 如果当前节点的值小于
low
,意味着当前节点及其左子树中的所有节点都小于low
,不符合要求。 - 这时,应该跳过当前节点和左子树,递归处理右子树。
- 返回右子树的修剪结果作为新的子树。
2. 当前节点值大于 high
if(root.val > high) return trimBST(root.left, low, high);
- 如果当前节点的值大于
high
,意味着当前节点及其右子树中的所有节点都大于high
,不符合要求。 - 这时,应该跳过当前节点和右子树,递归处理左子树。
- 返回左子树的修剪结果作为新的子树。
3. 当前节点符合范围
root.left = trimBST(root.left, low, high);
root.right = trimBST(root.right, low, high);
return root;
- 如果当前节点的值在
[low, high]
范围内,保留当前节点。 - 对当前节点的左子树和右子树分别递归调用
trimBST
,修剪它们。 - 将修剪后的左子树和右子树分别赋值给
root.left
和root.right
。 - 返回当前节点
root
。
108.将有序数组转换为二叉搜索树
左闭右闭 左等于右合法
class Solution {public TreeNode sortedArrayToBST(int[] nums) {return traveal(nums, 0, num.length);}public TreeNode traveal(int[] nums, left, right) {//左闭右开 if(left >= right) return null; //left > righ 左闭右闭int mid = (left + right) / 2; //int mid = left + ((right - left) >> 1); 改进版TreeNode root = new TreeNode(nums[mid]); //创建二叉搜索树的根节点root.left = traveal(nums, left, mid); //(nums, left, mid - 1) 左闭右闭root.right = traveal(nums, mid + 1,right) //(nums, mid + 1, right) 左闭右闭return root;}
}
538.把二叉搜索树转换为累加树
class Solution {//双指针 累加前面的题有这样的写法int pre = 0;public TreeNode convertBST(TreeNode cur) {if(cur == null) return null;convertBST(cur.right); cur.val += pre;pre = cur.val;convertBST(cur.left);return cur;}
}
为什么用反中序遍历?
1. 二叉搜索树的性质:
- 在中序遍历中,BST 的节点值是从小到大的顺序。
- 反中序遍历(右-根-左)则是从大到小的顺序。
2. 累加树的构建规则:
- 计算累加和时,需要从最大的节点开始累加。
- 依次向前,当前节点的值加上之前所有节点的累加和(即
pre
变量),再将结果赋给当前节点。
二叉树总结篇
大体分分类。
- 涉及到二叉树的构造,无论普通二叉树还是二叉搜索树一定前序,都是先构造中节点。
- 求普通二叉树的属性,一般是后序,一般要通过递归函数的返回值做计算。
- 求二叉搜索树的属性,一定是中序了,运用有序性了。
注意在普通二叉树的属性中,我用的是一般为后序,例如单纯求深度就用前序,leetcode257.找所有路径也用了前序,这是为了方便让父节点指向子节点。