669. 修剪二叉搜索树
该题首先需要明确函数的定义:
// 删除当前树中所有小于low,大于high的节点,返回结果BST
public TreeNode trimBST(TreeNode root, int low, int high)
明确之后进行思考,如果一个节点没有落入[lo, hi]区间内应该怎么操作:
1、root.val < lo
,这种情况下 root
节点本身和 root
的左子树全都是小于 lo
的,都需要被剪掉。
2、root.val > hi
,这种情况下 root
节点本身和 root
的右子树全都是大于 hi
的,都需要被剪掉。
所以写出以下完整代码:
class Solution {
// 删除当前树中所有小于low,大于high的节点,返回结果BST
public TreeNode trimBST(TreeNode root, int low, int high) {
if(root == null){
return null;
}
if(root.val < low){
// 删除该节点,及其左子树上的所有节点 -> 直接返回递归该节点的右子树 root.right
return trimBST(root.right, low, high);
}
if(root.val > high){
// 删除该节点,及其右子树上的所有节点 -> 直接返回递归该节点的右子树 root.left
return trimBST(root.left, low, high);
}
// root.val 在[low,high]之间,则不用动
root.left = trimBST(root.left, low, high);
root.right = trimBST(root.right, low, high);
return root;
}
}
108.将有序数组转换为二叉搜索树
考虑到二叉搜索树的特性:(中序遍历结果是有序的)
一个有序数组对于 BST 来说就是中序遍历结果,根节点在数组中心,数组左侧是左子树元素,右侧是右子树元素。
则选择利用分治思想进行构造二叉搜索树
完整代码如下:
class Solution {
public TreeNode sortedArrayToBST(int[] nums) {
return build(nums, 0, nums.length - 1);
}
// 将闭区间 [left, right] 中的元素转化成 BST,返回根节点
TreeNode build(int[] nums, int left, int right) {
if (left > right) {
// 区间为空
return null;
}
// 构造根节点
// BST 节点左小右大,中间的元素就是根节点
int mid = (left + right) / 2;
TreeNode root = new TreeNode(nums[mid]);
// 递归构建左子树
root.left = build(nums, left, mid - 1);
// 递归构造右子树
root.right = build(nums, mid + 1, right);
return root;
}
}
538.把二叉搜索树转换为累加树
由于题目中要求每个节点 node
的新值等于原树中大于或等于 node.val
的值之和。
所以在BST中可知便是加上当前节点右子树上的值并重新赋值即可
注:由于需要先获取右子树上的值,才能进行累加(选择反中序遍历,先遍历右子树)
完整代码如下:
class Solution {
public TreeNode convertBST(TreeNode root) {
traverse(root);
return root;
}
int sum = 0;
public void traverse(TreeNode root){
if(root == null){
return;
}
traverse(root.right);
sum += root.val;
root.val = sum;
traverse(root.left);
}
}