669.修剪二叉搜索树
思路:采用后序递归遍历,先从最下面将不符合条件的节点删除。采用自下往上的顺序,这样当遍历到应当删除的节点时,该节点的左右孩子一定有一个也是不符合条件的,而且已经被删除了,所以删除该节点只需要返回左右子树中不为空的那个就好。
class Solution {
public TreeNode trimBST(TreeNode root, int low, int high) { // 后序递归遍历
if (root == null) return null;
if (root.left != null) root.left = trimBST(root.left, low, high);
if (root.right != null) root.right = trimBST(root.right, low, high);
if (root.val < low || root.val >high) { // 要删除该节点,若节点不符合条件,左右孩子一定有一个已经被删除了。
if (root.left == null) return root.right;
if (root.right == null) return root.left;
}
return root;
}
}
108.将有序数组转换为二叉搜索树
思路:题目要求构成一个左右平衡的二叉树,我们先找到数组的中间节点,作为根节点,然后从根据中间节点左边的数组构建左子树,中间节点右边的数组构建右子树。这样递归的来构建就是一个左右平衡的二叉树。
class Solution {
public TreeNode sortedArrayToBST(int[] nums) {
return getSearchTree(nums, 0, nums.length);
}
public TreeNode getSearchTree(int[] nums, int start, int end) { // 左闭右开
if (start >= end) return null;
int mid = (start + end) / 2;
TreeNode node = new TreeNode(nums[mid]);
node.left = getSearchTree(nums, start, mid);
node.right = getSearchTree(nums, mid + 1, end);
return node;
}
}
538.把二叉搜索树转换为累加树
思路:本题同样利用二叉搜索树的特性,二叉搜索树的中序遍历是有序的。根据累加树规则,我们可以进行右中左的中序遍历,这样遍历的节点值是递减的,我们可以定义count累加前面遍历过的节点的值,这样count就是当前节点在累加树中的值。
class Solution {
private int count = 0;
public TreeNode convertBST(TreeNode root) { // 采用右中左的中序遍历
if (root == null) return null;
convertBST(root.right);
count += root.val;
root.val = count;
convertBST(root.left);
return root;
}
}
二叉树总结
二叉树题目中的注意点
1、二叉树中大部分题目使用递归,要想到递归三部曲(1、确定返回值,参数。2、确定终止条件。3、确定单层逻辑。)
2、二叉树的题目遍历顺序非常重要,拿到一个题目首先要确定遍历顺序。
3、遇到二叉搜索树的题目,不要忘记二叉搜索树中序遍历的特性。
二叉树题目类型
1、二叉树构造类题目,一定是前序。
2、求解普通二叉树属性,一般情况下是后序(根据递归的返回值做计算),具体情况具体分析遍历顺序。
3、求解二叉搜索树属性,一定要优先考虑中序遍历的特性。