【算法训练营】二叉树专题(二)

简介: 【算法训练营】二叉树专题(二)

前言

本篇为二叉树专题的刷题题单,总共6道题,每道题都有对应的链接。

边听歌边刷题吧~

🎸Phantom

654. 最大二叉树

链接: 最大二叉树

解题思路

  • 每次以当前数组中最大的那个值为分割点
  • 将数组分为左右子树构建左子树和右子树

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* constructMaximumBinaryTree(vector<int>& nums) { 
    if(nums.size()==0)return nullptr; 
    int maxnum=0; 
    for(int i=0;i<nums.size();++i) { 
        if(nums[i]>nums[maxnum])maxnum=i; 
    } 
    int rootVal=nums[maxnum]; 
    TreeNode* root=new TreeNode(rootVal); 
    if(nums.size()==1)return root; 
    vector<int> nleftTree(nums.begin(),nums.begin()+maxnum); 
    vector<int> nrightTree(nums.begin()+maxnum+1,nums.end()); 
    root->left=constructMaximumBinaryTree(nleftTree); 
    root->right=constructMaximumBinaryTree(nrightTree); 
    return root;
    } 
};

617. 合并二叉树

链接:617. 合并二叉树

解题思路

  • 由题可得,两颗树都有的节点就相加
  • 一个树没有就将另一棵树的那一节直接加到新的树的节点

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==nullptr)return root2;
        if(root2==nullptr)return root1;
        TreeNode* root = new TreeNode(0);
        root->val = root1->val + root2->val;
        root->left = mergeTrees(root1->left,root2->left);
        root->right = mergeTrees(root1->right,root2->right);
        return root;
    }
};

700. 二叉搜索树中的搜索

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

解题思路

  • 题目要求返回BST 中找到节点值等于 val 的节点的子树
  • 其实就是找到那个节点
  • 已知这颗树是二叉搜索树,那么就可以利用左边比根节点大,右边比根节点小的性质
  • 其次还要使用一个变量来记录搜索的返回值
  • 终止条件是节点为NULL时,说明到了叶子节点还没有找到
  • 或者是节点的值相等说明找到了

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 || root->val == val) return root;
        TreeNode* result=nullptr;
        if(root->val > val)result = searchBST(root->left,val);
        if(root->val < val)result = searchBST(root->right,val);
        return result;
    }
};

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:
    TreeNode* pre=nullptr;
    bool isValidBST(TreeNode* root) {
        if(root==nullptr)return true;//如果二叉搜索树为空,它也是二叉搜索树
        bool l=isValidBST(root->left);
        //中序遍历时,二叉搜索树是顺序递增的(不包含重复元素)
        if(pre!=nullptr&&pre->val >= root->val)return false;
        pre=root;//记录前一个节点的值
        bool r=isValidBST(root->right);
        return l&&r;
    }
};
迭代法
class Solution {
public:
    bool isValidBST(TreeNode* root) {
        stack<TreeNode*> st;
        TreeNode* cur = root;
        TreeNode* pre = NULL; // 记录前一个节点
        while (cur != NULL || !st.empty()) {
            if (cur != NULL) {
                st.push(cur);
                cur = cur->left;                // 左
            } else {
                cur = st.top();                 // 中
                st.pop();
                if (pre != NULL && cur->val <= pre->val)
                return false;
                pre = cur; //保存前一个访问的结点
                cur = cur->right;               // 右
            }
        }
        return true;
    }
};

530. 二叉搜索树的最小绝对差

链接:530. 二叉搜索树的最小绝对差

解题思路

  • 求最小差值、绝对值
  • 已知二叉搜索树的中序遍历是递增且不含重复元素的
  • 故可使用中序遍历,用一个变量记录前一个节点,如果前一个节点不为空则对比最小值
  • 也可以将这个二叉搜索树的中序遍历为一个数组,然后遍历数组。
  • 还可以使用栈来将树按照中序遍历的顺序读取然后比较

AC代码

递归法
class Solution {
public:
    TreeNode*pre = nullptr;
    int res=INT_MAX;
    void getMinGap(TreeNode* root){
        if(root==nullptr)return;
        getMinGap(root->left);
        if(pre!=nullptr){
            res=min(res,root->val-pre->val);
        }
        pre=root;
        getMinGap(root->right);
    }
    int getMinimumDifference(TreeNode* root) {
        getMinGap(root);
        return res;
    }
};
数组法
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:
    int getMinimumDifference(TreeNode* root) {
        vec.clear();
        traversal(root);
        if (vec.size() < 2) return 0;
        int result = INT_MAX;
        for (int i = 1; i < vec.size(); i++) { // 统计有序数组的最小差值
            result = min(result, vec[i] - vec[i-1]);
        }
        return result;
    }
};
迭代法
class Solution {
public:
    int getMinimumDifference(TreeNode* root) {
        stack<TreeNode*> st;
        TreeNode* cur = root;
        TreeNode* pre = NULL;
        int result = INT_MAX;
        while (cur != NULL || !st.empty()) {
            if (cur != NULL) { // 指针来访问节点,访问到最底层
                st.push(cur); // 将访问的节点放进栈
                cur = cur->left;                // 左
            } else {
                cur = st.top();
                st.pop();
                if (pre != NULL) {              // 中
                    result = min(result, cur->val - pre->val);
                }
                pre = cur;
                cur = cur->right;               // 右
            }
        }
        return result;
    }
};

501. 二叉搜索树中的众数

链接:501. 二叉搜索树中的众数

解题思路

  • 根据二叉搜索树的性质可以使用中序遍历
  • 使用计数器记录相同的数字
  • 一个记录前一个节点的变量,需要判断和前一个是否相同
  • 如果节点不同就需要判断数量大小
  • 数量相同就存入数组
  • 数量更多就把数组清空将新的节点的数字存入数组,然后重新计数
  • 如果碰到节点数字和前一个不同就将计数重置,更新pre

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* pre=nullptr;
    vector<int> v;
    int maxcount=0;
    int count=0;
    void travel(TreeNode* root){
        if(root==nullptr)return;
        travel(root->left);
        if(pre->val == root->val)count++;
        else if(pre->val != root->val){
            pre = root;
            count=1;
        }
        if(count==maxcount){
            v.push_back(root->val);
        }
        if(count>maxcount)
        {
            maxcount=count;
            v.clear();
            v.push_back(root->val);
        }
        travel(root->right);
        return;
    }
    vector<int> findMode(TreeNode* root) {
        pre = root;
        travel(root);
        return v;
    }
};


相关文章
|
7天前
|
算法
分享一些提高二叉树遍历算法效率的代码示例
这只是简单的示例代码,实际应用中可能还需要根据具体需求进行更多的优化和处理。你可以根据自己的需求对代码进行修改和扩展。
|
10天前
|
存储 缓存 算法
如何提高二叉树遍历算法的效率?
选择合适的遍历算法,如按层次遍历树时使用广度优先搜索(BFS),中序遍历二叉搜索树以获得有序序列。优化数据结构,如使用线索二叉树减少空指针判断,自定义节点类增加辅助信息。利用递归与非递归的特点,避免栈溢出问题。多线程并行遍历提高速度,注意线程安全。缓存中间结果,避免重复计算。预先计算并存储信息,提高遍历效率。综合运用这些方法,提高二叉树遍历算法的效率。
29 5
|
13天前
|
机器学习/深度学习 JSON 算法
二叉树遍历算法的应用场景有哪些?
【10月更文挑战第29天】二叉树遍历算法作为一种基础而重要的算法,在许多领域都有着不可或缺的应用,它为解决各种复杂的问题提供了有效的手段和思路。随着计算机科学的不断发展,二叉树遍历算法也在不断地被优化和扩展,以适应新的应用场景和需求。
24 0
|
1月前
|
存储 机器学习/深度学习 算法
蓝桥杯练习题(三):Python组之算法训练提高综合五十题
蓝桥杯Python编程练习题的集合,涵盖了从基础到提高的多个算法题目及其解答。
60 3
蓝桥杯练习题(三):Python组之算法训练提高综合五十题
|
17天前
|
分布式计算 Java 开发工具
阿里云MaxCompute-XGBoost on Spark 极限梯度提升算法的分布式训练与模型持久化oss的实现与代码浅析
本文介绍了XGBoost在MaxCompute+OSS架构下模型持久化遇到的问题及其解决方案。首先简要介绍了XGBoost的特点和应用场景,随后详细描述了客户在将XGBoost on Spark任务从HDFS迁移到OSS时遇到的异常情况。通过分析异常堆栈和源代码,发现使用的`nativeBooster.saveModel`方法不支持OSS路径,而使用`write.overwrite().save`方法则能成功保存模型。最后提供了完整的Scala代码示例、Maven配置和提交命令,帮助用户顺利迁移模型存储路径。
|
1月前
|
机器学习/深度学习 算法 决策智能
【机器学习】揭秘深度学习优化算法:加速训练与提升性能
【机器学习】揭秘深度学习优化算法:加速训练与提升性能
|
1月前
|
存储 算法 关系型数据库
数据结构与算法学习二一:多路查找树、二叉树与B树、2-3树、B+树、B*树。(本章为了解基本知识即可,不做代码学习)
这篇文章主要介绍了多路查找树的基本概念,包括二叉树的局限性、多叉树的优化、B树及其变体(如2-3树、B+树、B*树)的特点和应用,旨在帮助读者理解这些数据结构在文件系统和数据库系统中的重要性和效率。
19 0
数据结构与算法学习二一:多路查找树、二叉树与B树、2-3树、B+树、B*树。(本章为了解基本知识即可,不做代码学习)
|
1月前
|
存储 算法 搜索推荐
数据结构与算法学习十七:顺序储存二叉树、线索化二叉树
这篇文章主要介绍了顺序存储二叉树和线索化二叉树的概念、特点、实现方式以及应用场景。
20 0
数据结构与算法学习十七:顺序储存二叉树、线索化二叉树
|
1月前
|
存储 算法
【二叉树】—— 算法题
【二叉树】—— 算法题
【二叉树】—— 算法题
|
1月前
|
算法 Java C++
【贪心算法】算法训练 ALGO-1003 礼物(C/C++)
【贪心算法】算法训练 ALGO-1003 礼物(C/C++)
【贪心算法】算法训练 ALGO-1003 礼物(C/C++)