669. 修剪二叉搜索树
力扣链接:https://leetcode.cn/problems/trim-a-binary-search-tree/
这道题使用递归写法。
容易存在的误区:遇到 root->val < low || root->val > high 的时候直接return NULL
![](https://i-blog.csdnimg.cn/blog_migrate/f968848e3c3fc7b18441c32d97f1f2e0.png)
实际上如果遇到不符合的节点直接return null,会导致这个节点以下的子节点全部丢失(样例中0节点为null之后下面的2和1都不存在了,整个二叉树就剩下3这个节点)。
这里需要根据二叉树的特性:
判断当前节点如果大于上界,那么说明可能这个节点的左节点会在范围内 - 递归左节点直到找到符合的节点然后返回;
判断当前节点如果小于下界,那么说明可能这个节点的右节点会在范围内 - 递归左节点直到找到符合的节点然后返回;
递归三部曲
输出以及输入参数:TreeNode;(TreeNode root, int low, int high)
终止条件:如果node为null, 返回null
单层循环逻辑:如果node > high, 递归查找左子树节点,返回left;如果node < low, 递归查找右子树节点,返回right;确定root.left、root.right构造树
具体代码实现:
public TreeNode trimBST(TreeNode root, int low, int high) {
if(root == null) return null;
if(root.val > high){
TreeNode left = trimBST(root.left, low, high);
return left;
}
if(root.val < low){
TreeNode right = trimBST(root.right, low, high);
return right;
}
root.left = trimBST(root.left, low, high);
root.right = trimBST(root.right, low, high);
return root;
}
参考资料:https://programmercarl.com/0669.修剪二叉搜索树.html#递归法
108.将有序数组转换为二叉搜索树
力扣链接:https://leetcode.cn/problems/convert-sorted-array-to-binary-search-tree/
这道题要求是高度平衡的二叉树,那么就需要从中间节点开始遍历;
即将中间节点作为根节点 - 之后大的节点作为右子树,小的节点作为左子树。
这里在找中间节点存在奇偶问题:
奇数的时候很好确定
但是偶数的时候需要怎么确定呢? - 统一取靠左还是靠右
递归三部曲:
输入以及输出参数:TreeNode;(int[], int left, int right)
终止条件:left>right -- return;
单层递归:找到middle值作为root节点,在left,middle-1中找root.left;在middle+1,right中找root.right
具体代码实现:
class Solution {
public TreeNode sortedArrayToBST(int[] nums) {
return helper(nums, 0, nums.length-1);
}
public TreeNode helper(int[] nums, int left, int right){
if(left > right) return null;
int middle = left+(right-left)/2;
TreeNode root = new TreeNode(nums[middle]);
root.left = helper(nums, left, middle-1);
root.right = helper(nums, middle+1, right);
return root;
}
}
参考资料:https://programmercarl.com/0108.将有序数组转换为二叉搜索树.html#递归
538.把二叉搜索树转换为累加树
力扣链接:https://leetcode.cn/problems/convert-bst-to-greater-tree/
首先需要理解题目的意思:
本题是想将对节点处 - 比节点大的节点中的数进行一个累加。
![](https://i-blog.csdnimg.cn/blog_migrate/814c8d0eb6686fd226560ec24ca01f2d.png)
如果将其转换成一个数组[0,1,2,3,4,5,6,7,8]
那就是从后往前进行累加[36,36,35,33,30,26,21,15,8]
之前在做二叉树遍历的时候 - 中序遍历(左中右):可以得到一个从小到大排列的有序数组
而这里是从最大的位置开始累加,因此是倒序的 - 可以考虑(右中左)遍历
递归三部曲:
确定输出以及输入参数:void;(TreeNode);一个全局变量sum [如果放到函数里去传递会出错 - 终止条件直接返回;导致丢失]
确定终止条件 - 当遇到null节点则return
单层循环:先遍历到右节点处,将sum中的值加入中间节点,并更新sum值,然后再遍历左节点
具体代码实现:
class Solution {
public TreeNode convertBST(TreeNode root) {
TreeNode node = root;
Helper(node);
return root;
}
int sum = 0;
public void Helper(TreeNode node){
if(node == null){
return;
}
Helper(node.right);//右
node.val += sum;//中
sum = node.val;
Helper(node.left);//左
}
}
参考资料:https://programmercarl.com/0538.把二叉搜索树转换为累加树.html#迭代法