代码随想录算法训练营第23天 | 538. 把二叉搜索树转换为累加树,108. 将有序数组转换为二叉搜索树,669. 修剪二叉搜索树
669. 修剪二叉搜索树
- 去模拟 举例 想一遍 如果该节点小于low 应该要去遍历他的右子树 去除比Low小的 return right
- 如果没找到的话 就返回的是null
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public TreeNode trimBST(TreeNode root, int low, int high) {
//终止条件
if(root==null) return null;
//如果该节点值小于Low 那就去递归该节点的右子树 因为右子树中有可能存在比Low大的值 然后返回右子树的头节点
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. 将有序数组转换为二叉搜索树
- 构造二叉树 一般是把树分为左区间和右区间
- 由于题目要求说 要平衡的 说明高度差不能超过1
- 所以从中最中间的节点作为 根节点 这样左子树 就在左边 右子树 就在右边 个数也相等
- 递归下去 左子树 的根节点 也在数组左半区间的 中间 区间可以定义成左闭右闭
- 至于若数组元素个数 为偶数个 中间节点位置靠左和靠右是 一样的 两种结构 都行
- 终止条件 由于定义的区间为左闭右闭 那么当左边界 > 右边界时 结束
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public TreeNode sortedArrayToBST(int[] nums) {
return traversal(nums,0,nums.length-1);
}
public TreeNode traversal(int[] nums,int left,int right){
//终止条件
//区间定义为左闭右闭
if(left>right) return null;
//找根节点
int mid = (left+right)/2;
TreeNode root = new TreeNode(nums[mid]);
//向左右递归
root.left = traversal(nums,left,mid-1);
root.right = traversal(nums,mid+1,right);
return root;
}
}
538. 把二叉搜索树转换为累加树
- 因为中序遍历 获得的是从小到大的升序数组 所以反过来 右中左遍历累加 符合题意 用全局变量sum
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
int sum = 0;
public TreeNode convertBST(TreeNode root) {
traversal(root);
return root;
}
public void traversal(TreeNode root){
//终止条件
if(root==null) return;
//右中左遍历 值是从小到大的 每个节点的值就是前面节点加上本节点值
traversal(root.right);
//中 这一层遍历的操作
//累加每一次的节点值
sum+=root.val;
//把sum赋值给当前root
root.val = sum;
//向左遍历
traversal(root.left);
return;
}
}
双指针
- 定义全局变量pre 指向前一个节点 右中左遍历累加
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
//int sum = 0;
TreeNode pre =null;
public TreeNode convertBST(TreeNode root) {
traversal(root);
return root;
}
public void traversal(TreeNode root){
//终止条件
if(root==null) return;
//右中左遍历 值是从小到大的 每个节点的值就是前面节点加上本节点值
traversal(root.right);
//中
if(pre!=null){
root.val+=pre.val;
}
pre = root;
traversal(root.left);
return;
}
}