669. 修剪二叉搜索树
设计递归函数traversal(node)
,返回的是以node为根节点的符合要求的子树
现在枚举所有情况
- 如果node是空,那么返回空
- 如果node是叶子节点
- 如果不在区间内,返回空
- 如果在区间内,返回node
- 如果node不是叶子节点
- 如果node在区间内
node.left = traversal(node.left); node.right = traversal(node.right)
- 返回node
- 如果node小于下限,那么node的左子树一定也全部小于下限,因此只可能保留右子树或者右子树的一部分,因此
return traversal(node.right)
- 如果node大于上限,那么node的右子树一定也全部大于上限,因此只可能保留左子树或者左子树的一部分,因此
return traversal(node.left)
- 如果node在区间内
class Solution {
int low2;
int high2;
public TreeNode trimBST(TreeNode root, int low, int high) {
low2 = low;
high2 = high;
return traversal(root);
}
TreeNode traversal(TreeNode node) {
if (node == null) return null;
// 是叶子节点
if (node.right == null && node.left == null) {
if (low2 <= node.val && node.val <= high2) {
return node;
} else {
return null;
}
}
// 不是叶子节点
if (low2 <= node.val && node.val <= high2) {
node.left = traversal(node.left);
node.right = traversal(node.right);
return node;
} else if (node.val < low2) {
return traversal(node.right);
} else {
return traversal(node.left);
}
}
}
108.将有序数组转换为二叉搜索树
因为要实现平衡,因此每次干的就是取中间一个节点,然后左右两边递归构造
设计递归函数traversal(int[] arr)
,返回一课利用arr构造的二叉搜索树
枚举所有有返回值的情况:
- 如果arr.length == 0,返回null
- 如果arr.length == 1,返回node(arr[0])
- 如果length >= 2
- 找到arr[arr.length / 2],这个就是二叉搜索树的根节点,此时arr就被切分成了
[leftArr, root, rightArr]
root.left = traversal(leftArr); root.right = traversal(rightArr)
- 返回root
- 找到arr[arr.length / 2],这个就是二叉搜索树的根节点,此时arr就被切分成了
class Solution {
public TreeNode sortedArrayToBST(int[] nums) {
return traversal(nums);
}
TreeNode traversal(int[] arr) {
if (arr.length == 0) return null;
if (arr.length == 1) return new TreeNode(arr[0]);
int rootIndex = arr.length % 2 == 0 ? arr.length / 2 - 1 : arr.length / 2;
TreeNode root = new TreeNode(arr[rootIndex]);
int[] leftArr = Arrays.copyOfRange(arr, 0, rootIndex);
int[] rightArr = Arrays.copyOfRange(arr, rootIndex + 1, arr.length);
root.left = traversal(leftArr);
root.right = traversal(rightArr);
return root;
}
}
538.把二叉搜索树转换为累加树
我觉得这道题按照“右中左”的顺序遍历,设置一个类的属性count,初始化为0,然后每次处理中节点就是
node.val += count
count = node.val
class Solution {
int sum;
public TreeNode convertBST(TreeNode root) {
sum = 0;
traversal(root);
return root;
}
void traversal(TreeNode node) {
if (node == null) return;
// 右
traversal(node.right);
// 中
node.val += sum;
sum = node.val;
// 左
traversal(node.left);
}
}
二叉树总结
- 涉及到二叉树的构造,无论普通二叉树还是二叉搜索树一定前序,都是先构造中节点。
- 求普通二叉树的属性,一般是后序,一般要通过递归函数的返回值做计算。
- 求二叉搜索树的属性,一定是中序了,要不白瞎了有序性了。