代码随想录算法训练营第二十天| LC654. 最大二叉树、LC617. 合并二叉树、LC700. 二叉搜索树中的搜索、LC98. 验证二叉搜索树

LeetCode 654 最大二叉树

题目链接:654. 最大二叉树

做题情况:做完106. 从中序与后序遍历序列构造二叉树后,再来做这道题目,只要注意做106题时候所需要注意的细节,感觉本题目要简单很多且很容易ac出来,下面是是自己ac代码:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    //遵循左闭右开原则
    TreeNode* traversal(vector<int>& nums, int Begin, int End){
        if(Begin==End)return NULL;
        int rootValue = *max_element(nums.begin()+Begin,nums.begin()+End);
        int rootIndex = max_element(nums.begin()+Begin,nums.begin()+End)-nums.begin();
        TreeNode* root=new TreeNode(rootValue);

        if(End-Begin==1)return root;

        int leftBegin = Begin;
        int leftEnd = rootIndex;

        int rightBegin = rootIndex+1;
        int rightEnd = End;

        root->left = traversal(nums, leftBegin, leftEnd);
        root->right = traversal(nums, rightBegin, rightEnd);

        return root;
    }

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

看完卡哥视频和代码随想录书相关部分后,才知道上述代码是优化后代码的写法,利用数组索引下标来实现主要的思考过程是需要每次都要定义一个新的vector(也就是数组)来实现不优化的版本,然后再通过利用数组索引下标来实现优化版本,在做时候要牢记递归三部曲就没有那么容易写错,且构造树时候一般采用前序遍历的写法,卡哥通过此题目也说明了是否加if判断这只是不同的代码风格的实现,具体的思考过程代码以及最终代码参考卡哥的所给出的。

LeetCode 617 合并二叉树

题目链接:617. 合并二叉树

做题情况:牢记递归三部曲来做这道题目就很容易ac出来,下面是自己独立做时候的ac代码:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
        if(root1==NULL&&root2==NULL)return NULL;
        
        if(root1!=NULL&&root2==NULL){
            return root1; 
        }
        
        if(root1==NULL&&root2!=NULL){
            return root2; 
        }

        int value1 = root1->val;
        int value2 = root2->val;
        int value= value1 + value2;
        TreeNode* root= new TreeNode(value);
        root->left = mergeTrees(root1->left, root2->left);
        root->right= mergeTrees(root1->right,root2->right);
        return root;
    }
};

看完卡哥视频和代码随想录书相关部分后,卡哥所给出代码是直接在原一棵树上进行构造二叉树,没有再重新构造一棵树了,这样可以节省空间效率实际上本题目采用何种遍历顺序都可以,只不过前序遍历更容易理解,且本题目也可以使用迭代法来解决,在二叉树对称的时候把两棵树的节点同时加入进行比较,关键通过本题目要掌握同时处理两棵二叉树的方法,具体代码参考卡哥所给。

LeetCode 700 二叉搜索树中的搜索

题目链接:700. 二叉搜索树中的搜索

做题情况:独立做本题目时候,自己严格遵循递归三部曲写出来递归版本,具体ac代码如下:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    TreeNode* searchBST(TreeNode* root, int val) {
        if(root==NULL)return NULL;
        if(root->val==val){
            return root;
        }else if(root->val>val){
            return searchBST(root->left, val);
        }else{
            return searchBST(root->right, val);
        }
        return NULL;
    }
};

对于迭代版本的写法看完卡哥视频和代码随想录书相关部分后才写出,实际上也并不难,具体如下:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
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;
    }
};

通过本题目,自己对二叉搜索树的相关特性和一些操作有了很深的了解,相当于是做二叉搜索树的入门题目了

LeetCode 98 验证二叉搜索树

题目链接:98. 验证二叉搜索树

做题情况:独立做本题目时候自己采用中序遍历得到一个数组然后然后判断这个数组是否是严格升序的来判断是否是二叉搜索树,具体ac代码如下:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    vector<int>vec;
    void traversal(TreeNode* root){
        if(root==NULL)return;
        traversal(root->left);
        vec.push_back(root->val);
        traversal(root->right);
    }

    bool isValidBST(TreeNode* root) {
        traversal(root);
        for(int i=vec.size()-1;i>0;i--){
            if(vec[i]<=vec[i-1]){
                return false;
            }
        }
        return true;
    }
};

看完卡哥视频和代码随想录书相关部分后,知道本题目直接可以在递归遍历时候判断是否有序,不过要注意两个陷阱:① 不能单纯的比较左节点小于中间节点,右节点大于中间节点就完事了。② 样例中最小节点可能是int的最小值,如果这时候使用最小的int=来比较也是不行的。要注意使用在递归时候的双指针写法,具体ac代码如下(这里是卡哥所给的代码):

class Solution {
public:
    TreeNode* pre = NULL; // 用来记录前一个节点
    bool isValidBST(TreeNode* root) {
        if (root == NULL) return true;
        bool left = isValidBST(root->left);

        if (pre != NULL && pre->val >= root->val) return false;
        pre = root; // 记录前一个节点

        bool right = isValidBST(root->right);
        return left && right;
    }
};

本题目也可以使用中序遍历的迭代版本来写,具体参考卡哥所给的

今天的四道题目自己独立做时候花了两三个小时都ac出来了,但是还是有很多细节没有搞明白和所花费时间挺长的,以及多种写法(比如二叉搜索树的搜索的迭代版本不会写)自己只会其中一种写法啥的,有待继续努力,总共花了六个小时左右。

贵在坚持,加油,共勉

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值