代码随想录训练营第二十天|654.最大二叉树617.合并二叉树700.二叉搜索树中的搜索98.验证二叉搜索树

654.最大二叉树

采用递归的方法,总体思路为先找到最大元素作为根节点,然后以此对于左右进行分割,形成新的数组,在新数组中继续以上的行为,直到新数组仅剩1个元素退出递归

class Solution {
public:
    TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
        TreeNode *node = new TreeNode(0);
        if(nums.size()==1){
            node->val = nums[0];
            return node;
        }

        int maxVal = 0;
        int maxValIndex = 0;
        for (int i = 0;i < nums.size();i++) {
            if(nums[i]>maxVal){
                maxVal = nums[i];
                maxValIndex = i;
            }  
        }
        node->val = maxVal;

        if(maxValIndex>0){
            vector<int> newVec(nums.begin(),nums.begin()+maxValIndex);
            node->left=constructMaximumBinaryTree(newVec);
        }
        if(maxValIndex<nums.size()-1){
            vector<int> newVec(nums.begin()+maxValIndex,nums.end());
            node->right = constructMaximumBinaryTree(newVec);
        }
        return node;
    }
};

但是这个代码在力扣上无法提交,因为量太大:

进行优化,不再创建新的数组,而是在原数组上尽心操作:

代码中定义了一个名为Solution的类,该类包含一个私有成员函数traversal和一个公共成员函数constructMaximumBinaryTree

traversal函数用于递归地构造最大二叉树。它接受一个整数向量nums、左边界left和右边界right作为参数,并返回构造的二叉树的根节点。

在函数中,首先判断左边界是否大于等于右边界,如果是,说明当前区间内没有节点,返回空指针。

然后,通过遍历区间内的节点,找到值最大的节点,将其作为当前区间的根节点。

接下来,递归地构造根节点的左子树和右子树。左子树的节点范围是左闭右开区间[left, maxValueIndex),右子树的节点范围是左闭右开区间[maxValueIndex + 1, right)

最后,将构造的左子树和右子树分别赋给根节点的左指针和右指针,并返回根节点。

constructMaximumBinaryTree函数是公共成员函数,用于调用traversal函数并返回构造的最大二叉树的根节点。它接受一个整数向量nums作为参数,并调用traversal函数来构造最大二叉树。

整个程序的逻辑是通过递归地将每个区间划分为左右两个子区间,并在每个子区间中选取值最大的节点作为当前区间的根节点,直到区间为空为止。最终返回构造的最大二叉树的根节点。

class Solution {
private:
    // 在左闭右开区间[left, right),构造二叉树
    TreeNode* traversal(vector<int>& nums, int left, int right) {
        if (left >= right) return nullptr;

        // 分割点下标:maxValueIndex
        int maxValueIndex = left;
        for (int i = left + 1; i < right; ++i) {
            if (nums[i] > nums[maxValueIndex]) maxValueIndex = i;
        }

        TreeNode* root = new TreeNode(nums[maxValueIndex]);

        // 左闭右开:[left, maxValueIndex)
        root->left = traversal(nums, left, maxValueIndex);

        // 左闭右开:[maxValueIndex + 1, right)
        root->right = traversal(nums, maxValueIndex + 1, right);

        return root;
    }
public:
    TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
        return traversal(nums, 0, nums.size());
    }
};

617.合并二叉树

本体采用递归思路:

输入两个二叉树的根节点,输出的是一个二叉树的根节点;

终止条件为两个树中的一个为空;

单层循环条件就是以一个树为基础,加上另一个树的值;

class Solution {
public:
    TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
        if(root1==nullptr) return root2;
        if(root2==nullptr) return root1;

        root1->val += root2->val;
        root1->left = mergeTrees(root1->left, root2->left);
        root1->right = mergeTrees(root1->right, root2->right);
        return root1;
    }
};

迭代法:

class Solution {
public:
    TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) {
        if (t1 == NULL) return t2;
        if (t2 == NULL) return t1;
        queue<TreeNode*> que;
        que.push(t1);
        que.push(t2);
        while(!que.empty()) {
            TreeNode* node1 = que.front(); que.pop();
            TreeNode* node2 = que.front(); que.pop();
            // 此时两个节点一定不为空,val相加
            node1->val += node2->val;

            // 如果两棵树左节点都不为空,加入队列
            if (node1->left != NULL && node2->left != NULL) {
                que.push(node1->left);
                que.push(node2->left);
            }
            // 如果两棵树右节点都不为空,加入队列
            if (node1->right != NULL && node2->right != NULL) {
                que.push(node1->right);
                que.push(node2->right);
            }

            // 当t1的左节点 为空 t2左节点不为空,就赋值过去
            if (node1->left == NULL && node2->left != NULL) {
                node1->left = node2->left;
            }
            // 当t1的右节点 为空 t2右节点不为空,就赋值过去
            if (node1->right == NULL && node2->right != NULL) {
                node1->right = node2->right;
            }
        }
        return t1;
    }
};

700.二叉搜索树中的搜索

采用递归法,输入需要搜索的二叉树和目标值,返回子二叉树;

终止条件为搜索到目标值

单层循环为当root->val>val时,searchBST(root->left,val);当root->val<val时,searchBST(root->right,val)

class Solution {
public:
    TreeNode* searchBST(TreeNode* root, int val) {

        if(root==nullptr||root->val==val)
            return root;

        TreeNode *result;
        if(root->val>val)
            result = searchBST(root->left, val);
        if(root->val<val)
            result = searchBST(root->right, val);
        return result;
    }
};

迭代法:

class Solution
{
public:
    TreeNode *searchBST(TreeNode *root, int val)
    {
        while (root != NULL)
        {
            if (root->val > val)
                root = root->left;
            else if (root->val < val)
                root = root->right;
            else
                return root;
        }
        return NULL;
    }
};

98.验证二叉搜索树 

采用先将二叉树转为数组,然后通过数组进行对比的方法

在转换成数组的过程中采用递归法:

class Solution {
private:
    vector<int> vec;
    void traversal(TreeNode* root) {
        if (root == NULL) return;
        traversal(root->left);
        vec.push_back(root->val); // 将二叉搜索树转换为有序数组
        traversal(root->right);
    }
public:
    bool isValidBST(TreeNode* root) {
        vec.clear(); // 不加这句在leetcode上也可以过,但最好加上
        traversal(root);
        for (int i = 1; i < vec.size(); i++) {
            // 注意要小于等于,搜索树里不能有相同元素
            if (vec[i] <= vec[i - 1]) return false;
        }
        return true;
    }
};

  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值