day23|LeetCode:● 669. 修剪二叉搜索树 ● 108.将有序数组转换为二叉搜索树 ● 538.把二叉搜索树转换为累加树

题目链接:669. 修剪二叉搜索树

1.思路

题目:

给你二叉搜索树的根节点 root ,同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树,使得所有节点的值在[low, high]中。修剪树 不应该 改变保留在树中的元素的相对结构 (即,如果没有被移除,原有的父代子代关系都应当保留)。 可以证明,存在 唯一的答案 。

2.我们前序遍历找到不符合的点,然后再遍历左右边可能符合条件的点,直到遍历到最后,条件中返回的是不包含不符合范围的左子树或右子树。

2.递归法

class Solution {
public:
   TreeNode* traversal(TreeNode* root, int low, int high) {
       if (root == NULL) return NULL;
       if (root->val < low) {
           TreeNode*right = traversal(root->right, low, high);
           return right;
       }
       if (root->val > high) {
           TreeNode* left = traversal(root->left, low, high);
           return left;
       }
       root->left = traversal(root->left, low, high);
       root->right = traversal(root->right, low, high);
       return root;
   }
    TreeNode* trimBST(TreeNode* root, int low, int high) {
      return traversal(root, low, high);
    }
};

精简后:

class Solution {
public:
    TreeNode* trimBST(TreeNode* root, int low, int high) {
        if (root == nullptr) return nullptr;
        if (root->val < low) return trimBST(root->right, low, high);
        if (root->val > high) return trimBST(root->left, low, high);
        root->left = trimBST(root->left, low, high);
        root->right = trimBST(root->right, low, high);
        return root;
    }
};

3.递归三部曲

1.确定返回类型和参数类型:因为是修剪二叉树,最后还是返回二叉树,为treenode,传入返回和根节点

2.确定终止条件:当遍历到空节点时,返回空给叶子结点的左右子树

3.确定单层递归的逻辑:遍历二叉树中的结点需要先判断结点符不符合规格,所以先序判断一下,不符合规格就返回符合规格的子树,子树还要进行判断最后返回符合规格的叶子结点,最后返回root,再到上一层,因为在中的逻辑中已经跳过了不符合逻辑的点返回上一层,所以最后就是修剪后的子树

推测靠先序,理解看后序


题目链接:108. 将有序数组转换为二叉搜索树

1.思路

将数组构造成平衡二叉搜索树,一般用前序遍历,挑选出中间点,再递归挑选左右边子树的根。奇数和偶数相同的逻辑。

2.递归法

class Solution {
public:
     TreeNode*traversal(vector<int>& nums, int left, int right) {
        if (left > right) return NULL;
        int mid = left + right >> 1;
        TreeNode* root = new TreeNode(nums[mid]);
        root->left = traversal(nums,left, mid - 1);
        root->right = traversal(nums, mid + 1, right);
        return root;                                                              
    }
    TreeNode* sortedArrayToBST(vector<int>& nums) {
     return traversal(nums, 0, nums.size() - 1);
    }
};

3.递归三部曲

1.确定返回类型和参数类型:因为要构造二叉树,所以就要返回根结点TreeNode ,传入数组,因为每一次我们都要缩减数组范围,所以需要传入左边界和右边界。

左边界和右边界的定义:都可以。但后面的逻辑会不相同

2.确定终止条件:当遇到空结点时返回空为叶子结点的左右子树。

3.确定单层递归的逻辑,因为构造二叉树,每次都前序新增结点,左右遍历再把结点加入左子树和右子树,最后从叶子结点逐步返回到了根结点。


题目链接:538. 把二叉搜索树转换为累加树

1.思路

题目的意思是把比当前结点大的(就是右子树)值和当前结点的值相加变成当前结点的值。因为是二叉搜索树,要充分利用二叉搜索树的特性,为中序遍历,又因为是把大的相加,需要倒序,所以用右中左。利用双指针不断把值传给上一层。

2.递归法

class Solution {
public:
    TreeNode*pre = nullptr;
    void traversal(TreeNode* cur) {
        if (cur == nullptr) return;
        traversal(cur->right);
        if (pre != nullptr) {
          cur->val += pre->val;
        }
        pre = cur;
        traversal(cur->left);
    }
    TreeNode* convertBST(TreeNode* root) {
     traversal(root);
     return root;
    }
};

3.递归三部曲

1.确定返回类型和返回参数:因为是修改结点,直接返回void,传入树的根结点。

2.确定返回类型,当遍历到空结点时,直接返回上一层,同步指针。

3.确定单层递归的逻辑:因为是中序遍历,结点的值都是有顺序的遍历到的,每次遍历都需要同步结点,同步前需要进行相加如果这个不是叶子结点的时候。最后不断向上。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值