669.修剪二叉搜索树
题目链接:669. 修剪二叉搜索树 - 力扣(LeetCode)
该题目最开始是想找到low和high的位置,然后根据条件判断将所有不符合条件的结点一并删除,不过这样处理是比较复杂的,需要考虑的特殊情况很多。
参考了优秀的答案,发现使用递归法更加优秀清晰。
做这个题的误区就是想如何一次给所有不符合条件的结点全删除,而没有去想如何将大问题分解成相同的小问题,用迭代法去求解。
用递归法去做题的时候首先还是要想清楚:
这个函数的要做的是什么,根据函数的返回值等信息,思考这个问题如何拆解成相同的以他左右孩子为根的子问题
能想清楚这一点,递归应该就不成问题了。
class Solution {
public TreeNode trimBST(TreeNode root, int low, int high) {
// 当前函数是返回在low和high区间的二叉搜索树
// 终止条件
if(root == null) return null;
if(root.val < low){ // 当前结点不符合条件了,将他删除后的右子树返回(转化成子问题了)
TreeNode right = trimBST(root.right, low, high);
return right;
}
if(root.val > high){
TreeNode left = trimBST(root.left, low, high);
return left;
}
root.left = trimBST(root.left, low, high);
root.right = trimBST(root.right, low, high);
return root;
}
}
108.将有序数组转换成二叉搜索树
题目链接:108. 将有序数组转换为二叉搜索树 - 力扣(LeetCode)
解题思路:因为树本身的性质:二叉搜索树,所以题目也就变的简单了。
class Solution {
public TreeNode sortedArrayToBST(int[] nums) {
// 由于是已经排过序的数组了,所以我们只需要不断对半拆分迭代即可。
return createTree(nums, 0, nums.length);
}
public TreeNode createTree(int[] nums, int begin, int end){ // 数组区间左闭右开
if(begin >= end) return null;
int mid = begin + ((end - begin) >> 1);
TreeNode root = new TreeNode(nums[mid]);
root.left = createTree(nums, begin, mid);
root.right = createTree(nums, mid + 1, end);
return root;
}
}
538.把二叉搜索树转换成累加树
题目链接:538. 把二叉搜索树转换为累加树 - 力扣(LeetCode)
解题思路:
先遍历了一遍,求了个和,然后再中序遍历一点点减,这是第一想法,但是这个做法有点呆,明明可以直接右中左方式遍历直接加的,我这次局限于使用某种遍历方式了。不应该有这种局限要随机应变!
class Solution {
int sum = 0;
public TreeNode convertBST(TreeNode root) {
// 先遍历一次树,计算树中所有结点的和
sum = getSum(root);
// 中序遍历,边遍历边删
inorder(root);
return root;
}
public void inorder(TreeNode root){
// 终止条件
if(root == null) return;
inorder(root.left); // 左
int tmp = root.val;
root.val = sum;
sum -= tmp;
inorder(root.right); // 右
return;
}
public int getSum(TreeNode root){
if(root == null) return 0;
int sum = 0;
sum += root.val;
if(root.left != null) sum += getSum(root.left);
if(root.right != null) sum += getSum(root.right);
return sum;
}
}
不睿智的写法如下:
class Solution {
int sum = 0;
public TreeNode convertBST(TreeNode root) {
// 反向中序遍历,边遍历边求和
reinorder(root);
return root;
}
public void reinorder(TreeNode root){
// 终止条件
if(root == null) return;
reinorder(root.right); // 左
sum += root.val;
root.val = sum;
reinorder(root.left); // 右
return;
}
}