leetcode-zgd-day23-669.修剪二叉搜索树/108.将有序数组转换成二叉搜索树/538.把二叉搜索树转换成累加树

34 阅读2分钟

669.修剪二叉搜索树

题目链接:669. 修剪二叉搜索树 - 力扣(LeetCode)

该题目最开始是想找到low和high的位置,然后根据条件判断将所有不符合条件的结点一并删除,不过这样处理是比较复杂的,需要考虑的特殊情况很多。

参考了优秀的答案,发现使用递归法更加优秀清晰。

做这个题的误区就是想如何一次给所有不符合条件的结点全删除,而没有去想如何将大问题分解成相同的小问题,用迭代法去求解。

用递归法去做题的时候首先还是要想清楚:

这个函数的要做的是什么,根据函数的返回值等信息,思考这个问题如何拆解成相同的以他左右孩子为根的子问题

能想清楚这一点,递归应该就不成问题了。

 class Solution {
     
     public TreeNode trimBST(TreeNode root, int low, int high) {
         // 当前函数是返回在low和high区间的二叉搜索树
         // 终止条件
         if(root == null) return null;
         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.将有序数组转换成二叉搜索树

题目链接:108. 将有序数组转换为二叉搜索树 - 力扣(LeetCode)

解题思路:因为树本身的性质:二叉搜索树,所以题目也就变的简单了。

 class Solution {
     public TreeNode sortedArrayToBST(int[] nums) {
         // 由于是已经排过序的数组了,所以我们只需要不断对半拆分迭代即可。
         return createTree(nums, 0, nums.length);
     }
     public TreeNode createTree(int[] nums, int begin, int end){ // 数组区间左闭右开
         if(begin >= end) return null;
         int mid = begin + ((end - begin) >> 1);
         TreeNode root = new TreeNode(nums[mid]);
         root.left = createTree(nums, begin, mid);
         root.right = createTree(nums, mid + 1, end);
         return root;
     }
 }

538.把二叉搜索树转换成累加树

题目链接:538. 把二叉搜索树转换为累加树 - 力扣(LeetCode)

解题思路:

先遍历了一遍,求了个和,然后再中序遍历一点点减,这是第一想法,但是这个做法有点呆,明明可以直接右中左方式遍历直接加的,我这次局限于使用某种遍历方式了。不应该有这种局限要随机应变!

 class Solution {
 ​
     int sum = 0;
 ​
     public TreeNode convertBST(TreeNode root) {
         // 先遍历一次树,计算树中所有结点的和
         sum = getSum(root);
         // 中序遍历,边遍历边删
         inorder(root);
         return root;
     }
     public void inorder(TreeNode root){
         // 终止条件
         if(root == null) return;
         inorder(root.left); // 左
         int tmp = root.val;
         root.val = sum;
         sum -= tmp;
         inorder(root.right); // 右
         return;
     }
     public int getSum(TreeNode root){
         if(root == null) return 0;
         int sum = 0;
         sum += root.val;
         if(root.left != null) sum += getSum(root.left);
         if(root.right != null) sum += getSum(root.right);
         return sum;
     }
 }

不睿智的写法如下:

 class Solution {
     int sum = 0;
     public TreeNode convertBST(TreeNode root) {
         // 反向中序遍历,边遍历边求和
         reinorder(root);
         return root;
     }
     public void reinorder(TreeNode root){
         // 终止条件
         if(root == null) return;
         reinorder(root.right); // 左
         sum += root.val;
         root.val = sum;
         reinorder(root.left); // 右
         return;
     }
 }