代码随想录day23
题669 修剪二叉搜索树
给定一个二叉搜索树,同时给定最小边界L 和最大边界 R。通过修剪二叉搜索树,使得所有节点的值在[L, R]中 (R>=L) 。你可能需要改变树的根节点,所以结果应当返回修剪好的二叉搜索树的新的根节点。
思考:
1,递归,此题需要注意的是要分节点值小于low和大于high分开判断,不能一刀切。
(1)当节点值小于low时:则该节点和左子树都应该被剪掉,应该返回剪枝后的右子树。
(2)当节点值大于high时:该节点和右子树都应该被剪掉,返回剪枝后的左子树。
(3)当位于区间之间时:分别递归左右子树。
class Solution {
public TreeNode trimBST(TreeNode root, int low, int high) {
if(root == null) return null;
if(root.val < low){
root = trimBST(root.right, low, high);
} else if(root.val > high){
root = trimBST(root.left, low, high);
} else{
root.left = trimBST(root.left, low, high);
root.right = trimBST(root.right, low, high);
}
return root;
}
}
题108 将有序数组转换为二叉搜索树
将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树。
本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。
思考
1,因为是平衡二叉树,因此数组中中间的那个值一定是跟节点,前半个数组为左子树,后半个为右子树。于是递归即可。
启发:
1,在原函数基础上递归需要创建新的左右数组,可以写一个递归函数,传入数组和左右下标。
class Solution {
//方法2: 单独写一个递归函数
public TreeNode sortedArrayToBST(int[] nums) {
return creatBST(nums, 0, nums.length - 1);
}
//递归函数,传入数组左右下标,用下标之内的数组构建BST
public TreeNode creatBST(int[] nums, int left, int right){
if(left > right) return null;
int mid = (left + right) / 2;
TreeNode root = new TreeNode(nums[mid]);
root.left = creatBST(nums, left, mid - 1);
root.right = creatBST(nums, mid + 1, right);
return root;
}
//方法1: 在原函数基础上递归,每次递归都需要创建新的左数组和右数组
// public TreeNode sortedArrayToBST(int[] nums) {
// int len = nums.length;
// if(len == 0) return null;
// if(len == 1) return new TreeNode(nums[0]);
// int index = len/2;
// TreeNode root = new TreeNode(nums[index]);
// int[] left = new int[index];
// for(int i = 0; i < index; i++){
// left[i] = nums[i];
// }
// int[] right = new int[len - index - 1];
// for(int j = 0; j < len - index - 1; j++){
// right[j] = nums[index + 1 + j];
// }
// root.left = sortedArrayToBST(left);
// root.right = sortedArrayToBST(right);
// return root;
// }
}
题538 把二叉搜索树转换为累加树
给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。
启发:
1,想一下如果是一个数组进行累加是不是很容易,从最后一个元素开始遍历,每个元素的改为当前元素和前一个元素之和。
2,反中序遍历可以从最右边的元素(也是二叉搜索树中最大的元素)开始遍历二叉树。右中左的顺序,了解了这一点,就需要一个值来存放之前遍历过的元素之和。
class Solution {
/**
中序遍历bst可以得到一个递增的数组,但此题需要从最大的数值开始累加,因此右中左可以实现
*/
int sum = 0;//全局变量代表遍历过的元素的和
public TreeNode convertBST(TreeNode root) {
if(root == null) return null;
traversal(root);
return root;
}
//该函数以右中左的顺序遍历二叉树,在遍历的过程中对节点的值进行处理
public void traversal(TreeNode cur){
if(cur == null) return;
//处理右
traversal(cur.right);
//处理中
cur.val += sum;
sum = cur.val;
//处理左
traversal(cur.left);
}
}