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

52 篇文章 0 订阅

669. 修剪二叉搜索树

对于该题,对结点中的判断逻辑,如果为NULL,就返回NULL, 如果 < low, 则再次去遍历 该节点的右子树,因为右子树中可能会有符合条件的值, 对处理过的右子树进行返回, 同样的,如果 > high, 则再次去遍历 该结点的左子树,因为左子树可能会有符合条件的值, 对处理 过的左子树进行返回。

然后递归时,让结点的左子树 去 接住 处理过的左子树, 右子树 去接住处理过的右子树,然后进行返回。

再这里有个问题时,对于删除结点的内存的释放,这块还存在问题。

class Solution {
public:
    TreeNode* trimBST(TreeNode* root, int low, int 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.将有序数组转换为二叉搜索树

关于如何利用数组去构造二叉树的整体思路:

先选取一个中间的结点,将这个数组分为左区间 和 右区间,然后递归遍历左区间,然后构成了左子树,递归去遍历右区间,去构成了右子树。

对于本题而言,选取中间结点的时候一定要选取中间位置的结点,只有这样,才能保证它的左区间的结点数量和右区间的结点数量是相同的,这样构造出来的二叉树才能保证它是平衡的。将其分割后,左区间也选中间结点,再去左右分割,同样的,右区间也选中间结点,左右分割,这样就保证了它的每一层下面左右子树结点数量相同,然后根据二叉搜索树结点的性质进行构造。

当数组长度为奇数时,取中间结点,当为偶数时,取中间偏左或者偏右的结点都是可以的,只不过两者的构造顺序略有差异。

对于数组作为函数参数时,对C++ 语言而言,建议使用引用,不然会引起内存空间的重复copy,这样就会导致程序的性能很差。 其他语言就没有这个问题,自带内存回收机制。

对于数组的区间,一定要明确 是 左闭右闭呢, 还是左闭右开

class Solution {
public:
    TreeNode* sortedArrayToBST(vector<int>& nums) {
        return traversal(nums, 0, nums.size() - 1);
    }
    // 区间为 左 闭 右 闭[]
    TreeNode* traversal(vector<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.把二叉搜索树转换为累加树

根据题目中给的顺序而言,将二叉搜索树转换为数组的话,就是从后往前累加,切换回二叉树的话,就是右中左去累加,也就是中序遍历的反向。
利用双指针法,保存上一个结点的值,在这里可以用指针,也可以用int 值,因为只需要保存值。

class Solution {
public:
    TreeNode* convertBST(TreeNode* root) {
        traversal(root);
        return root;
    }
    TreeNode* pre = NULL;
    void traversal(TreeNode* node) {
        if (node == NULL) return;
        traversal(node->right);
        if (pre != NULL) node->val += pre->val;
        pre = node;
        traversal(node->left);
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值