视频讲解:
你修剪的方式不对,我来给你纠正一下!| LeetCode:669. 修剪二叉搜索树_哔哩哔哩_bilibili
思路:结合BST的定义以及特点,以小于low为例,小于low的某个节点无非位于左子树或者右子树,位于左子树,左边全部是删除的目标;位于右子树,右子树左侧的所有节点全部删掉,所以只有删除位置的右子树有用;其次,删除的方向要自底向上,避免不满足low和high范围的节点存在于深度高的部位,在仅仅删除上面不满足要求节点后直接把下面不符合要求节点直接赋值回去了。
/**
* 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;
* }
* }
*/
// 时间复杂度o(n)
// 空间复杂度O(1)
class Solution {
public TreeNode trimBST(TreeNode root, int low, int high) {
if(root == null)
return null;
root.left = trimBST(root.left, low, high);
root.right = trimBST(root.right, low, high);
if(root.val < low)
return root.right;
if(root.val > high)
return root.left;
return root;
}
// public TreeNode deletenode(TreeNode root, int target){
// // 确定停止条件
// if(root == null)
// return null;
// // BST中左右子树的操作所返回的结果都是独立的,彼此之间无需再做额外的复核处理
// if(root.val > target){
// root.left = deletenode(root.right, target);
// return root;
// }
// if(root.val < target){
// root.right = deletenode(root.left, target);
// return root;
// }
// if(root.val == target){
// // 找到待删除的节点
// // 此时待删除节点又可以分为好几种情况
// if(root.left == null && root.right == null)
// return null;
// if(root.left != null && root.right == null)
// return root.left;
// if(root.left == null && root.right != null)
// return root.right;
// if(root.left != null && root.right != null){
// // 找左子树最右
// TreeNode pre = root.left;
// while(pre!= null && pre.right != null)
// pre = pre.right;
// // pre此时位于的就是替换root的节点
// pre.right = root.right;
// root = root.left;
// }
// return root;
// }
// return root;
// }
}
思路:题目中明确数组是有序,是绝佳的条件。其次题目要求形成的是平衡BST,从中间开始向两边逐个遍历输出BST的策略不满足要求。那么就和确定数组中间节点是root一样,不停二分,每次二分的位置都是子树的根节点。
/**
* 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;
* }
* }
*/
// 时间复杂度O(n)
// 空间复杂度O(1)
class Solution {
public TreeNode sortedArrayToBST(int[] nums) {
// 使用回溯思想结合递归
boolean[] visited = new boolean[nums.length];
return buildBST(nums, 0, nums.length-1, visited);
}
public TreeNode buildBST(int[] nums, int low, int high, boolean[] visited){
// 截止条件
if(low > high)
return null;
// 使用回溯的思想
int mid = low + (high-low)/2;
TreeNode root = null;
// 遍历的方向是先序
if(visited[mid] == false){
root = new TreeNode(nums[mid], null, null);
visited[mid] = true;
root.left = buildBST(nums, low, mid-1, visited);
root.right = buildBST(nums, mid+1, high, visited);
}
return root;
}
}
思路:记住他,反中序遍历,右中左。另外使用全局变量是妙笔,学到了。
/**
* 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;
* }
* }
*/
// 时间复杂度O(n)
// 空间复杂度O(1)
class Solution {
int sum = 0;
public TreeNode convertBST(TreeNode root) {
// 优先走到最右子节点
DFS(root);
return root;
}
public void DFS(TreeNode t){
if(t == null)
return;
// 反中序遍历
DFS(t.right);
sum += t.val;
t.val = sum;
DFS(t.left);
return;
}
}