[代码随想录]二叉树

news2024/9/27 17:28:06

二叉树

文章目录

    • 二叉树
      • 1. 二叉树的递归遍历
        • 144.前序遍历
        • 94.中序遍历
        • 145.后续遍历
      • *2.二叉树的迭代遍历
        • 145.前序遍历
        • 94.中序遍历
        • 145.后续遍历
      • 3.统一二叉树迭代遍历
        • 144.前序遍历
        • 94.中序排序
        • 145.后序遍历
      • 4.层序遍历
        • 102.二叉树的层序遍历
        • 107. 二叉树的层序遍历 II
        • 199. 二叉树的右视图
        • 637. 二叉树的层平均值
        • 429. N 叉树的层序遍历
        • 515. 在每个树行中找最大值
        • 116. 填充每个节点的下一个右侧节点指针
        • 117. 填充每个节点的下一个右侧节点指针 II
      • 5.翻转二叉树
        • 226.翻转二叉树
      • 6.对称二叉树
        • 101. 对称二叉树
        • 100. 相同的树
        • 572.另一个树的子树
      • 7.二叉树的最大深度
        • 104. 二叉树的最大深度
      • 8.二叉树的最小深度
        • 111.二叉树的最小深度
      • 9.完全二叉树节点个数
        • 222.完全二叉树节点个数
      • *10.平衡二叉树
        • 深度与高度区别:
      • 11.二叉树的所有路径
        • 257. 二叉树的所有路径
      • 12.左叶子之和
        • 404.左叶子之和
      • 13.找树左下角的值
        • 513.找树左下角的值
      • 14.路径总和
        • 112. 路径总和
        • 113. 路径总和 II
      • *15.从中序,后序遍历序列来构造二叉树
        • 106. 从中序与后序遍历序列构造二叉树
        • 105. 从前序与中序遍历序列构造二叉树
      • 16.最大二叉树
        • 654. 最大二叉树
      • 17.合并二叉树
        • 617.合并二叉树
      • 18.二叉搜索树中的搜索
        • 700.二叉搜索树中的搜索
      • 20.验证二叉搜索树
        • 98.验证二叉搜索树
      • 21.二叉搜索树的最小绝对差
        • 530.二叉搜索树的最小绝对差
      • 22. 二叉搜索树中的众数
        • 501. 二叉搜索树中的众数
      • **23. 二叉搜索树的最近公共祖先
        • 235. 二叉搜索树的最近公共祖先
      • 24.二叉搜索树中的插入操作
        • 701.二叉搜索树中的插入操作
      • 25.删除二叉搜索树中的节点
        • 450.删除二叉搜索树中的节点
      • 26. 修剪二叉搜索树
        • 669. 修剪二叉搜索树
      • 27.将有序数组转换为二叉搜索树
        • 108.将有序数组转换为二叉搜索树
      • *28.把二叉搜索树转换为累加树
        • 538.把二叉搜索树转换为累加树

二叉树可以链式存储,也可以顺序存储。

那么链式存储方式就用指针, 顺序存储的方式就是用数组。

顾名思义就是顺序存储的元素在内存是连续分布的,而链式存储则是通过指针把分布在各个地址的节点串联一起。

链式存储如图:

img

链式存储是大家很熟悉的一种方式,那么我们来看看如何顺序存储呢?

其实就是用数组来存储二叉树,顺序存储的方式如图:

img

用数组来存储二叉树如何遍历的呢?

如果父节点的数组下标是 i,那么它的左孩子就是 i * 2 + 1,右孩子就是 i * 2 + 2。

二叉树定义

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) {}
 * };

1. 二叉树的递归遍历

深度优先遍历:先往深走,遇到叶子节点再往回走

在深度优先遍历中:有三个顺序,前中后序遍历, 这三个顺序,经常搞混

记住技巧:这里前中后,其实指的就是中间节点的遍历顺序, 前中后序指的就是中间节点的位置。

递归写法技巧:

  1. 确定递归函数的参数和返回值: 确定哪些参数是递归的过程中需要处理的,那么就在递归函数里加上这个参数, 并且还要明确每次递归的返回值是什么进而确定递归函数的返回类型。
  2. 确定终止条件: 写完了递归算法, 运行的时候,经常会遇到栈溢出的错误,就是没写终止条件或者终止条件写的不对,操作系统也是用一个栈的结构来保存每一层递归的信息,如果递归没有终止,操作系统的内存栈必然就会溢出。
  3. 确定单层递归的逻辑: 确定每一层递归需要处理的信息。在这里也就会重复调用自己来实现递归的过程。

144.前序遍历

给你二叉树的根节点 root ,返回它节点值的 前序 遍历。

/**
 * 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:
    //前序
    void traversal(TreeNode* node,vector<int>&v){
        if(node == nullptr)return;
        v.push_back(node->val);
        traversal(node->left,v);
        traversal(node->right,v);
    }

    vector<int> preorderTraversal(TreeNode* root) {
        vector<int>v;
        traversal(root,v);
        return v;
    }
};

94.中序遍历

给定一个二叉树的根节点 root ,返回 它的 中序 遍历

/**
 * 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:
    void traversal(TreeNode* node,vector<int>&v){
        if(node == nullptr)return;
        traversal(node->left,v);
        v.push_back(node->val);
        traversal(node->right,v);
    }

    vector<int> inorderTraversal(TreeNode* root) {
        vector<int>v;
        traversal(root,v);
        return v;
    }
};

145.后续遍历

给你一棵二叉树的根节点 root ,返回其节点值的 后序遍历

/**
 * 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:
    void traversal(TreeNode* node,vector<int>&v){
        if(node == nullptr)return;
        traversal(node->left,v);
        traversal(node->right,v);
        v.push_back(node->val);
    }

    vector<int> postorderTraversal(TreeNode* root) {
        vector<int>v;
        traversal(root,v);
        return v;
    }
};

*2.二叉树的迭代遍历

栈其实就是递归的一种实现结构,也就说前中后序遍历的逻辑其实都是可以借助栈使用非递归的方式来实现的。

145.前序遍历

/**
 * 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> preorderTraversal(TreeNode* root) {
        stack<TreeNode*>st;
        TreeNode* curNode;
        vector<int>v;
        if(root == nullptr)return v;
        st.push(root);
        while(!st.empty()){
            curNode = st.top();
            st.pop();
            v.push_back(curNode->val);
            if(curNode->right)st.push(curNode->right);
            if(curNode->left)st.push(curNode->left);
        }
        return v;
    }
};

94.中序遍历

/**
 * 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> inorderTraversal(TreeNode* root) {
        stack<TreeNode*>st;
        TreeNode* curNode;
        vector<int>v;
        if(root == nullptr)return v;
        curNode = root;
        while(!st.empty() || curNode != nullptr){
            while(curNode){
                st.push(curNode);
                curNode = curNode->left;               
            }
            v.push_back(st.top()->val);
            curNode = st.top();
            st.pop();
            curNode = curNode->right;
        }
        return v;
    }
};

145.后续遍历

/**
 * 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> postorderTraversal(TreeNode* root) {
        stack<TreeNode*>st;
        TreeNode* curNode;
        vector<int>v;
        if(root == nullptr)return v;
        st.push(root);
        while(!st.empty()){
            curNode = st.top();
            v.push_back(st.top()->val);
            st.pop();
            if(curNode->left)st.push(curNode->left);
            if(curNode->right)st.push(curNode->right);
        }
        reverse(v.begin(),v.end());
        return v;
    }
};

3.统一二叉树迭代遍历

在中节点后插入一个标志,每个位置都会成为中节点,在按照顺序进行排序

自己总结一个技巧:

  • 前序:先把中节点当中节点,再把左节点当中节点,再把右节点当中节点
  • 中序:先把左节点当中节点,再把中节点当中节点,再把右节点当中节点
  • 后序:先把左节点当中节点,再把右节点当中节点,再把中节点当中节点

144.前序遍历

/**
 * 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> preorderTraversal(TreeNode* root) {
        TreeNode* curNode;
        vector<int>v;
        stack<TreeNode*>st;
        if(root == nullptr)return v;
        st.push(root);
        while(!st.empty()){
            curNode = st.top();
            if(curNode != nullptr){
                st.pop();
                if(curNode->right)st.push(curNode->right);
                if(curNode->left)st.push(curNode->left);
                st.push(curNode);
                st.push(nullptr);
            }
            else{
                st.pop();
                curNode = st.top();
                v.push_back(curNode->val);
                st.pop();
            }
        }
        return v;
    }
};

94.中序排序

/**
 * 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> inorderTraversal(TreeNode* root) {
        TreeNode* curNode;
        stack<TreeNode*>st;
        vector<int>v;
        if(root == nullptr)return v;
        st.push(root);
        while(!st.empty()){
            curNode = st.top();
            if(curNode != nullptr){
                st.pop();
                if(curNode->right)st.push(curNode->right);
                st.push(curNode);
                st.push(nullptr);
                if(curNode->left)st.push(curNode->left);
            }
            else{
                st.pop();
                curNode = st.top();
                v.push_back(curNode->val);
                st.pop();
            }
        }
        return v;
    }
};

145.后序遍历

/**
 * 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> postorderTraversal(TreeNode* root) {
        vector<int>v;
        TreeNode* curNode;
        stack<TreeNode*>st;
        if(root == nullptr)return v;
        st.push(root);
        while(!st.empty()){
            curNode = st.top();
            if(curNode != nullptr){
                st.push(nullptr);
                if(curNode->right)st.push(curNode->right);
                if(curNode->left)st.push(curNode->left);
            }
            else{
                st.pop();
                curNode = st.top();
                v.push_back(curNode->val);
                st.pop();
            }
        }
        return v;
    }
};

4.层序遍历

广度优先遍历:一层一层的去遍历。

广度优先遍历:层次遍历(递归法,迭代法)

广度优先遍历的实现一般使用队列来实现,这也是队列先进先出的特点所决定的,因为需要先进先出的结构,才能一层一层的来遍历二叉树。

102.二叉树的层序遍历

给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)。

1.递归法

/**
 * 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:
    void order(TreeNode* root,vector<vector<int>>& v,int depth){
        if(root == nullptr)return ;
        if(v.size() == depth)v.push_back(vector<int>());
        v[depth].push_back(root->val);
        order(root->left,v,depth + 1);
        order(root->right,v,depth + 1);
    }

    vector<vector<int>> levelOrder(TreeNode* root) {
        vector<vector<int>>v;
        int depth = 0;
        order(root,v,depth);
        return v;
    }
};

2.迭代法

/**
 * 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<vector<int>> levelOrder(TreeNode* root) {
        queue<TreeNode*>q;
        vector<vector<int>>res;
        TreeNode* node;
        if(root == nullptr)return res;
        q.push(root);
        while(!q.empty()){
            int OneLevelNum = q.size();
            vector<int>v;
            for(int i = 0;i < OneLevelNum;i++){
                node = q.front();
                q.pop();
                v.push_back(node->val);
                if(node->left)q.push(node->left);
                if(node->right)q.push(node->right);
            }
            res.push_back(v);
        }
        return res;
    }
};

107. 二叉树的层序遍历 II

给你二叉树的根节点 root ,返回其节点值 自底向上的层序遍历 。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)

/**
 * 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<vector<int>> levelOrderBottom(TreeNode* root) {
        vector<vector<int>>res;
        TreeNode*node;
        queue<TreeNode*>q;
        if(root != nullptr)q.push(root);
        while(!q.empty()){
            vector<int>v;
            int oneLeveSize = q.size();
            for(int i = 0;i < oneLeveSize;i++){
                node = q.front();
                q.pop();
                v.push_back(node->val);
                if(node->left)q.push(node->left);
                if(node->right)q.push(node->right);
            }
            res.push_back(v);
        }
        reverse(res.begin(),res.end());
        return res;
    }
};

199. 二叉树的右视图

给定一个二叉树的 根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。

/**
 * 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> rightSideView(TreeNode* root) {
        vector<int>res;
        TreeNode*node;
        queue<TreeNode*>q;
        if(root != nullptr)q.push(root);
        while(!q.empty()){
            vector<int>v;
            int oneLeveSize = q.size();
            for(int i = 0;i < oneLeveSize;i++){
                node = q.front();
                q.pop();
                v.push_back(node->val);
                if(node->left)q.push(node->left);
                if(node->right)q.push(node->right);
            }
            res.push_back(v.back());
        }
        return res;
    }
};

637. 二叉树的层平均值

给定一个非空二叉树的根节点 root , 以数组的形式返回每一层节点的平均值。与实际答案相差 10-5 以内的答案可以被接受。

/**
 * 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<double> averageOfLevels(TreeNode* root) {
        queue<TreeNode*>q;
        TreeNode* node;
        vector<double>v;
        if(root != nullptr)q.push(root);
        while(q.size()){
            double sum = 0;
            int leverSize = q.size();
            for(int i = 0;i < leverSize;i++){
                node = q.front();
                q.pop();
                sum += node->val;
                if(node->left)q.push(node->left);
                if(node->right)q.push(node->right);
            }
            double average = sum / leverSize;
            v.push_back(average);
        }
        return v;
    }
};

429. N 叉树的层序遍历

给定一个 N 叉树,返回其节点值的层序遍历。(即从左到右,逐层遍历)。

树的序列化输入是用层序遍历,每组子节点都由 null 值分隔

/*
// Definition for a Node.
class Node {
public:
    int val;
    vector<Node*> children;

    Node() {}

    Node(int _val) {
        val = _val;
    }

    Node(int _val, vector<Node*> _children) {
        val = _val;
        children = _children;
    }
};
*/

class Solution {
public:
    vector<vector<int>> levelOrder(Node* root) {
        vector<vector<int>> order;
        Node* node;
        queue<Node*>q;
        if(root != NULL)q.push(root);
        while(q.size()){
            vector<int>v;
            int levelSize = q.size();
            for(int i = 0;i < levelSize;i++){
                node = q.front();
                q.pop();
                v.push_back(node->val);
                if(node->children.size() != 0){
                    for(int j = 0;j < node->children.size();j++){
                        q.push(node->children[j]);
                    }
                }
            }
            order.push_back(v);
        }
        return order;
    }
};

515. 在每个树行中找最大值

给定一棵二叉树的根节点 root ,请找出该二叉树中每一层的最大值。

/**
 * 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> largestValues(TreeNode* root) {
        queue<TreeNode*>q;
        TreeNode* node;
        vector<int>v;
        if(root != nullptr) q.push(root);
        while(q.size()){
            int leverSize = q.size();
            int max = q.front()->val;
            for(int i = 0;i < leverSize;i++){
                node = q.front();
                q.pop();
                if(max < node->val){
                    max = node->val;
                }
                if(node->left)q.push(node->left);
                if(node->right)q.push(node->right);
            }
            v.push_back(max);
        }
        return v;
    }
};

116. 填充每个节点的下一个右侧节点指针

给定一个 完美二叉树 ,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:

struct Node {
  int val;
  Node *left;
  Node *right;
  Node *next;
}

填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL

初始状态下,所有 next 指针都被设置为 NULL

/*
// Definition for a Node.
class Node {
public:
    int val;
    Node* left;
    Node* right;
    Node* next;

    Node() : val(0), left(NULL), right(NULL), next(NULL) {}

    Node(int _val) : val(_val), left(NULL), right(NULL), next(NULL) {}

    Node(int _val, Node* _left, Node* _right, Node* _next)
        : val(_val), left(_left), right(_right), next(_next) {}
};
*/

class Solution {
public:
    Node* connect(Node* root) {
        Node* node;
        queue<Node*>q;
        if(root != NULL)q.push(root);
        while(q.size()){
            int leverSize = q.size();
            for(int i = 0;i < leverSize;i++){
                node = q.front();
                q.pop();
                if(i < leverSize - 1){
                    node->next = q.front();
                }
                if(node->left)q.push(node->left);
                if(node->right)q.push(node->right);
            }
        }
        return root;
    }
};

117. 填充每个节点的下一个右侧节点指针 II

给定一个二叉树

struct Node {
  int val;
  Node *left;
  Node *right;
  Node *next;
}

填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL

初始状态下,所有 next 指针都被设置为 NULL

/*
// Definition for a Node.
class Node {
public:
    int val;
    Node* left;
    Node* right;
    Node* next;

    Node() : val(0), left(NULL), right(NULL), next(NULL) {}

    Node(int _val) : val(_val), left(NULL), right(NULL), next(NULL) {}

    Node(int _val, Node* _left, Node* _right, Node* _next)
        : val(_val), left(_left), right(_right), next(_next) {}
};
*/

class Solution {
public:
    Node* connect(Node* root) {
        Node* node;
        queue<Node*>q;
        if(root != NULL)q.push(root);
        while(q.size()){
            int leverSize = q.size();
            for(int i = 0;i < leverSize;i++){
                node = q.front();
                q.pop();
                if(i < leverSize - 1){
                    node->next = q.front();
                }
                if(node->left)q.push(node->left);
                if(node->right)q.push(node->right);
            }
        }
        return root;
    }
};

5.翻转二叉树

226.翻转二叉树

给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。

1.递归法

/**
 * 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:
    //递归法
    void inver(TreeNode* node){
        if(node == nullptr)return ;
        swap(node->left,node->right);
        inver(node->left);
        inver(node->right);
    }
    TreeNode* invertTree(TreeNode* root) {
        inver(root);
        return root;
    }
};

2.迭代法

深度优先遍历

/**
 * 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* invertTree(TreeNode* root) {
        TreeNode* node;
        stack<TreeNode*>st;
        if(root != nullptr)st.push(root);
        while(st.size()){
            node = st.top();
            st.pop();
            swap(node->left,node->right);
            if(node->left)st.push(node->left);
            if(node->right)st.push(node->right);
        }
        return root;

广度优先遍历

/**
 * 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* invertTree(TreeNode* root) {
        queue<TreeNode*>q;
        TreeNode* node;
        if(root != nullptr)q.push(root);
        while(q.size()){
            int size = q.size();
            for(int i = 0;i < size;i++){
                node = q.front();
                q.pop();
                swap(node->left,node->right);
                if(node->left)q.push(node->left);
                if(node->right)q.push(node->right);
            }
        }
        return root;
    }
};

6.对称二叉树

101. 对称二叉树

给你一个二叉树的根节点 root , 检查它是否轴对称。

1.递归法

/**
* 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:
   bool isNot(TreeNode* left,TreeNode* right){
       if (left == NULL && right == NULL) return true;
       else if(left == NULL || right == NULL) return false;
       if(left->val != right->val)return false;
       bool one = isNot(left->left,right->right);
       bool two = isNot(left->right,right->left); 
       return one && two;
   }

   bool isSymmetric(TreeNode* root) { 
       if(root == nullptr)return true;       
       return isNot(root->left,root->right);
   }
};

2.迭代法

队列

/**
 * 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:
    bool isSymmetric(TreeNode* root) {
        if(root == nullptr)return true;
        queue<TreeNode*>q;
        TreeNode* left;
        TreeNode* right;
        q.push(root->left);
        q.push(root->right);
        while(q.size()){
            right = q.front();
            q.pop();
            left = q.front();
            q.pop();
            if(left == nullptr && right == nullptr) continue;
            if(!left || !right || left->val != right->val)return false;
            q.push(left->left);
            q.push(right->right);
            q.push(left->right);
            q.push(right->left);
        }
        return true;
    }
};

/**
 * 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:
    bool isSymmetric(TreeNode* root) {
        if(root == nullptr)return true;
        stack<TreeNode*>st;
        TreeNode* left;
        TreeNode* right;
        st.push(root->left);
        st.push(root->right);
        while(st.size()){
            right = st.top();
            st.pop();
            left = st.top();
            st.pop();
            if(left == nullptr && right == nullptr) continue;
            if(!left || !right || left->val != right->val)return false;
            st.push(left->left);
            st.push(right->right);
            st.push(left->right);
            st.push(right->left);
        }
        return true;
    }
};

100. 相同的树

给你两棵二叉树的根节点 pq ,编写一个函数来检验这两棵树是否相同。

如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。

/**
 * 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:
    bool isSameTree(TreeNode* p, TreeNode* q) {
        if(p == nullptr && q == nullptr)return true;
        queue<TreeNode*>q1;
        queue<TreeNode*>q2;
        if(p != nullptr && q != nullptr && q->val == p->val){
            q1.push(p);
            q2.push(q);
        }
        else return false;
        while(q1.size() && q2.size()){
            TreeNode* left = q1.front();
            q1.pop();
            TreeNode* right =q2.front();
            q2.pop();
            if(left == nullptr && right == nullptr)continue;
            if(!left || !right || left->val != right->val)return false;
            q1.push(left->left);
            q1.push(left->right);
            q2.push(right->left);
            q2.push(right->right);
        }
        return true;
    }
};

572.另一个树的子树

给你两棵二叉树 rootsubRoot 。检验 root 中是否包含和 subRoot 具有相同结构和节点值的子树。如果存在,返回 true ;否则,返回 false

二叉树 tree 的一棵子树包括 tree 的某个节点和这个节点的所有后代节点。tree 也可以看做它自身的一棵子树。

/**
 * 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:
    bool isSame(TreeNode* root,TreeNode * subRoot){
        queue<TreeNode*>left;
        queue<TreeNode*>right;
        if(root != nullptr && subRoot != nullptr && root->val == subRoot->val){
            left.push(root);
            right.push(subRoot);
        }
        else return false;
        while(left.size() && right.size()){
            TreeNode* curLeft = left.front();
            TreeNode* curright = right.front();
            left.pop();
            right.pop();
            if(curLeft == nullptr && curright == nullptr)continue;
            if(!curLeft || !curright || curLeft->val != curright->val)return false;
            left.push(curLeft->left);
            left.push(curLeft->right);
            right.push(curright->left);
            right.push(curright->right);
        }
        return true;
    }
    bool isSubtree(TreeNode* root, TreeNode* subRoot) {
        if(root == nullptr && subRoot == nullptr)return true;
        if(root == nullptr && subRoot != nullptr)return false;
        if(root != nullptr && subRoot == nullptr)return true;

        queue<TreeNode*>q;
        q.push(root);
        while(q.size()){
            TreeNode* cur = q.front();
            q.pop();
            bool is = isSame(cur,subRoot);
            if(is == true)return true;
            if(cur->left)q.push(cur->left);
            if(cur->right)q.push(cur->right);
        }
        return false;
    }
};

7.二叉树的最大深度

104. 二叉树的最大深度

给定一个二叉树,找出其最大深度。

二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。

/**
 * 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:
    int maxDepth(TreeNode* root) {
        queue<TreeNode*>q;
        if(root == nullptr)return 0;
        q.push(root);
        int sum = 0;
        while(q.size()){
            int oneSize = q.size();
            for(int i = 0;i < oneSize;i++){
                TreeNode* node = q.front();
                q.pop();
                if(node->left)q.push(node->left);
                if(node->right)q.push(node->right);
            }
            sum++;
        }
        return sum;
    }
};

8.二叉树的最小深度

111.二叉树的最小深度

给定一个二叉树,找出其最小深度。

最小深度是从根节点到最近叶子节点的最短路径上的节点数量。

/**
 * 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:
    int minDepth(TreeNode* root) {
       queue<TreeNode*>q;
        if(root == nullptr)return 0;
        q.push(root);
        int sum = 0;
        TreeNode* node;
        while(q.size()){
            int oneSize = q.size();
            for(int i = 0;i < oneSize;i++){
                node = q.front();
                q.pop();
                if(node->left ==nullptr && node->right == nullptr)break;
                if(node->left)q.push(node->left);
                if(node->right)q.push(node->right);
            }
            sum++;
            if(node->left ==nullptr && node->right == nullptr)break;

        }
        return sum;
    }
};

9.完全二叉树节点个数

完全二叉树的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2h 个节点。

222.完全二叉树节点个数

给你一棵 完全二叉树 的根节点 root ,求出该树的节点个数。

1.普通迭代,当做普普通通的二叉树节点个数来计算

/**
 * 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:
    int countNodes(TreeNode* root) {
        queue<TreeNode*>q;
        TreeNode* node;
        int  count = 0;
        if(root == nullptr)return count;
        q.push(root);
        while(!q.empty()){
            int OneLevelNum = q.size();
            for(int i = 0;i < OneLevelNum;i++){
                node = q.front();
                q.pop();
                if(node->left)q.push(node->left);
                if(node->right)q.push(node->right);
            }
            count += OneLevelNum;
        }
        return count;
    }
};

2.利用完全二叉树性质

完全二叉树只有两种情况,情况一:就是满二叉树,情况二:最后一层叶子节点没有满。

对于情况一,可以直接用 2^树深度 - 1 来计算,注意这里根节点深度为1。

对于情况二,分别递归左孩子,和右孩子,递归到某一深度一定会有左孩子或者右孩子为满二叉树,然后依然可以按照情况1来计算。

/**
 * 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:
    int countNodes(TreeNode* root) {
        int left = 0,right = 0;
        if(root == nullptr)return 0;
        TreeNode* leftNode = root->left;
        TreeNode* rightNode = root->right;
        while(leftNode){
            leftNode = leftNode->left;
            left++;
        }
        while(rightNode){
            rightNode = rightNode->right;
            right++;
        }
        if(left == right){
            return (2 << left) - 1;
        }
        return countNodes(root->left) + countNodes(root->right) + 1;//不要返回局部变量
    }
};

*10.平衡二叉树

深度与高度区别:

  • 二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数。
  • 二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数。

为求深度可以从上到下去查 所以需要前序遍历(中左右),而高度只能从下到上去查,所以只能后序遍历(左右中)

/**
 * 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:
    int height(TreeNode* node){
        if(node == nullptr)return 0;
        int left = height(node->left);
        if(left == -1)return -1;
        int right = height(node->right);
        if(right == -1)return -1;

        int maxHeight = 0;
        if(abs(left - right) > 1){
            return -1;
        }
        else{
            maxHeight = 1 + max(left,right);
            return maxHeight;
        }
        return maxHeight;
    }

    bool isBalanced(TreeNode* root) {
        if(height(root) == -1)return false;
        else return true;
    }
};

11.二叉树的所有路径

257. 二叉树的所有路径

给你一个二叉树的根节点 root ,按 任意顺序 ,返回所有从根节点到叶子节点的路径。

叶子节点 是指没有子节点的节点。

/**
 * 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:
    void treePaths(TreeNode* node,vector<int> &v,vector<string>&vs){
        string s;
        v.push_back(node->val);
        if(node->left == nullptr && node->right == nullptr){
            for(int i = 0; i < v.size() - 1;i++){
                s = s + to_string(v[i]);//将int转换为string
                s += "->";
            }
            s = s + to_string(v[v.size() - 1]);
            vs.push_back(s);
            return;
        }
        if(node->left){
            treePaths(node->left,v,vs);
            v.pop_back();//这条路访问完了,最后一个子节点删除
        }
        if(node->right){
            treePaths(node->right,v,vs);
            v.pop_back();
        }
    }

    vector<string> binaryTreePaths(TreeNode* root) {
        vector<int>v;
        vector<string>vs;
        treePaths(root,v,vs);
        return vs;
    }
};

12.左叶子之和

404.左叶子之和

计算给定二叉树的所有左叶子之和。

/**
 * 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:
    int sumOfLeftLeaves(TreeNode* root) {
        int sum = 0;
        stack<TreeNode*>st;
        if(root != nullptr)st.push(root);
        while(st.size()){
            TreeNode* node = st.top();
            if(node != nullptr){
                st.pop();
                if(node->right)st.push(node->right);
                st.push(node);
                st.push(nullptr);
                if(node->left){
                    st.push(node->left);
                    if(node->left->left == nullptr && node->left->right == nullptr){
                        sum += node->left->val;
                    }
                }
            }
            else{
                st.pop();
                st.pop();
            }
        }
        return sum;
    }
};

13.找树左下角的值

513.找树左下角的值

给定一个二叉树,在树的最后一行找到最左边的值。

/**
 * 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:
    int findBottomLeftValue(TreeNode* root) {
        int leftValue = 0;
        queue<TreeNode*>q;
        if(root != nullptr)q.push(root);
        while(q.size()){
            int size = q.size();
            leftValue = q.front()->val;
            for(int i = 0;i < size; i++){
                TreeNode* node = q.front();
                q.pop();
                if(node->left)q.push(node->left);
                if(node->right)q.push(node->right);
            }
        }
        return leftValue;
    }
};

14.路径总和

112. 路径总和

给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。

说明: 叶子节点是指没有子节点的节点。

/**
 * 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:
    bool isSum(TreeNode* node,int targetSum,vector<int>&v){
        if(node == nullptr)return false;
        v.push_back(node->val);
        int sum = 0;
        if(node->left == nullptr && node->right == nullptr){
            for(int i = 0;i < v.size();i++){
                sum += v[i];
            }
            if(sum == targetSum)return true;
        }
        if(node->left){
            bool isNot = isSum(node->left,targetSum,v);
            if(isNot == true)return true;
            v.pop_back();
        }
        if(node->right){
            bool isNot = isSum(node->right,targetSum,v);
            if(isNot == true)return true;
            v.pop_back();
        }
        return false;
    }
    bool hasPathSum(TreeNode* root, int targetSum) {
        vector<int>v;
        return isSum(root,targetSum,v);
    }
};

113. 路径总和 II

给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。

叶子节点 是指没有子节点的节点。

/**
 * 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:
    void path(TreeNode* node,int targetSum,vector<int>&v,vector<vector<int>>&vv){
        v.push_back(node->val);
        int sum = 0;
        if(node->left == nullptr && node->right == nullptr){
            for(int i = 0;i < v.size();i++){
                sum += v[i];
            }
            if(sum == targetSum){
                vv.push_back(v);
            }
        }
        if(node->left){
            path(node->left,targetSum,v,vv);
            v.pop_back();
        }
        if(node->right){
            path(node->right,targetSum,v,vv);
            v.pop_back();
        }
    }
    vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
        vector<vector<int>>vv;
        vector<int>v;
        if(root == nullptr)return vv;
        path(root,targetSum,v,vv);
        return vv;
    }
};

*15.从中序,后序遍历序列来构造二叉树

106. 从中序与后序遍历序列构造二叉树

给定两个整数数组 inorderpostorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树

/**
 * 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>& inorder, vector<int>& postorder){
        //根据后序排序来分割中序排序,通过中序排序左右边大小来分割后序排序左右边
        //靠后续排序值来确定二叉树

        if(postorder.size() == 0)return nullptr;

        TreeNode* root = new TreeNode(postorder[postorder.size() - 1]);
        int index = 0;//每次分割中间值所在中序排序的位置
        for(;index < inorder.size();index++){
            if(inorder[index] == root->val)break;
        }
        
        //中序分割
        //重定义数组为[ , );左闭右开
        vector<int>leftInorder(inorder.begin(),inorder.begin() + index);
        vector<int>rightInorder(inorder.begin() + index + 1,inorder.end());//中间index那位为中间点去掉

        vector<int>leftPostorder(postorder.begin(), postorder.begin() + index);
        vector<int>rightPostorder(postorder.begin() + index,postorder.end() - 1);//最后一位是中间点去掉

        root->right = traversal(rightInorder,rightPostorder);
        root->left = traversal(leftInorder,leftPostorder);

        return root;
    }

    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        if(postorder.size() == 0 || inorder.size() == 0)return nullptr;
        
        return traversal(inorder,postorder);
    }
};

105. 从前序与中序遍历序列构造二叉树

/**
 * 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* travel(vector<int>& preorder,vector<int>& inorder){
        if(preorder.size() == 0)return nullptr;

        TreeNode* root = new TreeNode(preorder[0]);

        int index = 0;
        for(;index < inorder.size();index++){
            if(inorder[index] == preorder[0]){
                break;
            }
        }

        vector<int>leftInorder(inorder.begin(),inorder.begin() + index);
        vector<int>rightInorder(inorder.begin() + index + 1,inorder.end());

        vector<int>leftPreorder(preorder.begin() + 1,preorder.begin() + index + 1);
        vector<int>rightPreorder(preorder.begin() + index + 1, preorder.end());

        root->left = travel(leftPreorder,leftInorder);
        root->right = travel(rightPreorder,rightInorder);

        return root;
    }

    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        if(preorder.size() == 0 || inorder.size() == 0){
            return nullptr;
        }

        return travel(preorder,inorder);
    }
};

16.最大二叉树

654. 最大二叉树

给定一个不重复的整数数组 nums最大二叉树 可以用下面的算法从 nums 递归地构建:

  1. 创建一个根节点,其值为 nums 中的最大值。
  2. 递归地在最大值 左边子数组前缀上 构建左子树。
  3. 递归地在最大值 右边子数组后缀上 构建右子树。

返回 nums 构建的 最大二叉树

/**
 * 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* maxTree(vector<int>& nums){
        //终止条件
        if(nums.size() == 0)return nullptr;
        
        //找最大值
        int max = 0;
        for(int index = 0;index < nums.size();index++){
            if(nums[index] > nums[max])max = index;
        }
        TreeNode* root = new TreeNode(nums[max]);

        vector<int>right(nums.begin() + max + 1,nums.end());
        vector<int>left(nums.begin(),nums.begin() + max);

        root->right = maxTree(right);
        root->left = maxTree(left);

        return root;
    }
    TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
        if(nums.size() == 0)return nullptr;
        return maxTree(nums);
    }
};

17.合并二叉树

617.合并二叉树

给你两棵二叉树: root1root2

想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。合并的规则是:如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值;否则,不为 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* merge(TreeNode* root1,TreeNode* root2){
        if(root2 == nullptr)return root1;

        if(root1 != nullptr)root1->val += root2->val;
        else if(root1 == nullptr) return root2;
        
        root1->left = merge(root1->left,root2->left);
        root1->right = merge(root1->right,root2->right);

        return root1;
    }

    TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
        if(root1 == nullptr && root2 == nullptr)return nullptr;
        if(root1 != nullptr && root2 == nullptr)return root1;
        if(root1 == nullptr && root2 != nullptr)return root2;
        
        return merge(root1,root2);
    }
};

18.二叉搜索树中的搜索

700.二叉搜索树中的搜索

给定二叉搜索树(BST)的根节点和一个值。 你需要在BST中找到节点值等于给定值的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 NULL。

1.没有利用搜索树特性

/**
 * 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:
    void bst(TreeNode* root, int val, TreeNode* &search){
        if(root == nullptr)return ;
        if(root->val == val)search = root;
        bst(root->left,val,search);
        bst(root->right,val,search);
    }
    TreeNode* searchBST(TreeNode* root, int val) {
        if(root == nullptr)return nullptr;
        TreeNode* search = nullptr;
        bst(root,val,search);
        return search;
    }
};

2.利用搜索树特性

/**
 * 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:
    void bst(TreeNode* root, int val, TreeNode* &search){
        if(root == nullptr)return ;
        if(root->val == val)search = root;
        if(root->val > val) bst(root->left,val,search);
        if(root->val < val) bst(root->right,val,search);
    }
    TreeNode* searchBST(TreeNode* root, int val) {
        if(root == nullptr)return nullptr;
        TreeNode* search = nullptr;
        bst(root,val,search);
        return search;
    }
};

20.验证二叉搜索树

98.验证二叉搜索树

给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。

有效 二叉搜索树定义如下:

  • 节点的左子树只包含 小于 当前节点的数。
  • 节点的右子树只包含 大于 当前节点的数。
  • 所有左子树和右子树自身必须也是二叉搜索树。

1.就放在中序遍历就可以,使遍历数字递增即可

递归

/**
 * 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:
    void travel(TreeNode* root,vector<int>&v){
        if(root == nullptr)return;
        travel(root->left,v);
        v.push_back(root->val);
        travel(root->right,v);
        return;
    }

    bool isValidBST(TreeNode* root) {
        vector<int>v;
        travel(root,v);

        for(int i = 0;i < v.size() - 1;i++){
            if(v[i] >= v[i + 1])return false;
        }
        return true;
    }
};

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

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

给你一棵所有节点为非负值的二叉搜索树,请你计算树中任意两节点的差的绝对值的最小值。

/**
 * 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:
    void travel(TreeNode* root,vector<int>&v){
        if(root == nullptr)return;
        travel(root->left,v);
        v.push_back(root->val);
        travel(root->right,v);
        return;
    }
    int getMinimumDifference(TreeNode* root) {
        vector<int>v;
        travel(root,v);
        int min = v[1] - v[0];
        for(int i = 1;i < v.size() - 1;i++){
            if((v[i + 1] - v[i]) < min)min = v[i + 1] - v[i];
            if(min == 1)return min;
        }
        return min;
    }
};

22. 二叉搜索树中的众数

501. 二叉搜索树中的众数

给你一个含重复值的二叉搜索树(BST)的根节点 root ,找出并返回 BST 中的所有 众数(即,出现频率最高的元素)。

如果树中有不止一个众数,可以按 任意顺序 返回。

假定 BST 满足如下定义:

  • 结点左子树中所含节点的值 小于等于 当前节点的值
  • 结点右子树中所含节点的值 大于等于 当前节点的值
  • 左子树和右子树都是二叉搜索树
/**
 * 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:
    void travel(TreeNode* node,map<int,int>&m){
        if(node == nullptr)return ;
        travel(node->right,m);
        m[node->val]++;
        travel(node->left,m);
        return;
    }
    vector<int> findMode(TreeNode* root) {
        map<int,int>m;
        vector<int>v;
        travel(root,m);
        auto it = m.begin();
        auto it1 = m.begin();
        v.push_back(it->first);
        it++;
        for(;it != m.end();it++){
            if(it->second > it1->second){
                v.clear();
                v.push_back(it->first);
                it1 = it;
            }
            else if(it->second == it1->second){
                v.push_back(it->first);
            }
        }
        return v;
    }
};

**23. 二叉搜索树的最近公共祖先

235. 二叉搜索树的最近公共祖先

给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5]

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */

class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if(root == q || root == p || root == NULL)return root;
        
        TreeNode* left =lowestCommonAncestor(root->left,p,q);
        TreeNode* right = lowestCommonAncestor(root->right,p,q);

        if(left != NULL && right != NULL)return root;
        else if(left != NULL && right == NULL)return left;
        else if(left == NULL && right != NULL)return right;
        else return NULL;
    }
};

24.二叉搜索树中的插入操作

701.二叉搜索树中的插入操作

给定二叉搜索树(BST)的根节点和要插入树中的值,将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据保证,新值和原始二叉搜索树中的任意节点值都不同。

注意,可能存在多种有效的插入方式,只要树在插入后仍保持为二叉搜索树即可。 你可以返回任意有效的结果。

/**
 * 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* insert(TreeNode* root,int val){
        if(val > root->val && root->right != nullptr){
            insert(root->right,val);
        }
        else if(val > root->val && root->right == nullptr){
            TreeNode* node = new TreeNode(val);
            root->right = node;
            return root;
        }
        else if(val < root->val && root->left != nullptr){
            insert(root->left,val);
        }
        else if(val < root->val && root->left == nullptr){
             TreeNode* node = new TreeNode(val);
            root->left = node;
            return root;
        }
        return root;
    }
    TreeNode* insertIntoBST(TreeNode* root, int val) {
        if(root == nullptr){
            TreeNode* node = new TreeNode(val);
            return node;
            }
        return insert(root,val);
    }
};

25.删除二叉搜索树中的节点

450.删除二叉搜索树中的节点

给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。

一般来说,删除节点可分为两个步骤:

首先找到需要删除的节点; 如果找到了,删除它。 说明: 要求算法时间复杂度为 O ( h ) O(h) O(h),h 为树的高度。

/**
 * 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* deleted(TreeNode*root,int key){
        if(root == nullptr)return root;
        if(root->val == key){
            if(root->left == nullptr && root->right == nullptr){
                delete root;
                return nullptr;
            }
            else if(root->left != nullptr && root->right == nullptr){
                TreeNode* node = root->left;
                delete root;
                return node;
            }
            else if(root->left == nullptr && root->right != nullptr){
                TreeNode* node = root->right;
                delete root;
                return node;
            }
            else{
                TreeNode* node = root->right;
                while(node->left){
                    node = node->left;
                }
                node->left = root->left;
                TreeNode* nodell = root;
                root = root->right;
                delete nodell;
                return root;
            }
        }
        else if(key > root->val){
            root->right = deleted(root->right,key);
        }
         else if(key < root->val){
            root->left = deleted(root->left,key);
        }
        return root;
    }
    TreeNode* deleteNode(TreeNode* root, int key) {
        if(root == nullptr ){
            return nullptr;
        }
        return deleted(root,key);
    }
};

26. 修剪二叉搜索树

669. 修剪二叉搜索树

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

所以结果应当返回修剪好的二叉搜索树的新的根节点。注意,根节点可能会根据给定的边界发生改变。

/**
 * 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* cut(TreeNode* root,int high,int low){
        if(root == nullptr)return root;
        if(root->val < low){
            return cut(root->right,high,low);
        }      
        else if(root->val > high){
            return cut(root->left,high,low);
        }
        root->left = cut(root->left,high,low);
        root->right = cut(root->right,high,low);
        
        return root;
    }

    TreeNode* trimBST(TreeNode* root, int low, int high) {
        if(root == nullptr)return nullptr;
        return cut(root,high,low);
    }
};

27.将有序数组转换为二叉搜索树

108.将有序数组转换为二叉搜索树

给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树。

高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。

/**
 * 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* travel(vector<int>&nums,int left,int right){
        if(left > right)return nullptr;
        int mid = (right + left)/2;
        TreeNode* node = new TreeNode(nums[mid]);
        node->right = travel(nums,mid+1,right);
        node->left = travel(nums,left,mid - 1);
        return node;
    }

    TreeNode* sortedArrayToBST(vector<int>& nums) {
        int left = 0;
        int right = nums.size() - 1;
        return travel(nums,left,right);
    }
};

*28.把二叉搜索树转换为累加树

538.把二叉搜索树转换为累加树

给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。

提醒一下,二叉搜索树满足下列约束条件:

  • 节点的左子树仅包含键 小于 节点键的节点。
  • 节点的右子树仅包含键 大于 节点键的节点。
  • 左右子树也必须是二叉搜索树。
/**
 * 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:
    void travel(TreeNode* root,int &num){
        if(root == nullptr)return ;
        if(root->right)travel(root->right,num);
        root->val += num;
        num = root->val;
        if(root->left)travel(root->left,num);
        return;
    }
    TreeNode* convertBST(TreeNode* root) {
        int num = 0;
        if(root == nullptr)return nullptr;
        travel(root,num);
        return root;
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/487475.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[Dev‘Life] Dubai工签指南

Dubai工作签证一般为两年有效期&#xff0c;主要流程为 PCR-TEST-REPORT&#xff08;体检&#xff09;劳动者通识培训(听课)申请ID (录制指纹/掌静脉) 前置查询&#xff1a;Dubai-ICA官网查看签证有效期 免费查询签证的状态&#xff0c;相关查询连接在此&#xff1a; https://…

与伙伴同行,Serverless 让创新触手可及

今天 Serverless 的方式真正意义上做到了云产品、云技术的开箱即用&#xff0c;企业和开发者不需要再关注底层的资源配置&#xff0c;更多地把精力放在业务系统的开发中。 4 月 26 日&#xff0c;在 2023 阿里云合作伙伴大会现场&#xff0c;阿里云智能 CTO 周靖人发表主题演讲…

XML解析(DOM4j)检索(Xpath)

XML在以后更多的是用来作为配置文件的。 一. 配置文件 什么是配置文件 用来保存程序在运行时需要的一些参数。 当配置信息比较复杂的时候&#xff0c;我们就可以用XML。 二. XML概述 三. XML的创建、语法规则 根标签就是写在最外面的标签。 <?xml version"1.0&quo…

【Unity3D小功能】Unity3D中实现Text显示版本功能

推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享简书地址我的个人博客 大家好&#xff0c;我是佛系工程师☆恬静的小魔龙☆&#xff0c;不定时更新Unity开发技巧&#xff0c;觉得有用记得一键三连哦。 一、前言 在项目开发中&#xff0c;会遇到要控制版本的情况&#xff0c;…

Python基础篇

大家好&#xff0c;我是易安&#xff01; Python语言比起C、Java等主流语言&#xff0c;语法更简洁&#xff0c;也更接近英语&#xff0c;对编程世界的新人还是很友好的&#xff0c;这也是其显著优点。最近总有人问我Python相关的问题&#xff0c;这些问题也偏基础&#xff0c;…

Qt绘图类

Qt绘图类 QPainter绘图1&#xff0e;QPainter与QPaintDevice2&#xff0e;paintEvent事件和绘图区3&#xff0e;QPainter绘图的主要属性4&#xff0e;创建实例 QPen的主要功能1&#xff0e;线条样式2&#xff0e;线条端点样式3. QBrush的主要功能4. 渐变填充 5 QPainter绘制…

Python小姿势 - Python连接MySQL数据库

Python连接MySQL数据库 Python是一种解释型、面向对象、动态数据类型的高级程序设计语言。 Python的创始人为吉多范罗苏姆&#xff08;Guido van Rossum&#xff09;&#xff0c;于1989年底圣诞节期间&#xff0c;为了打发无聊的圣诞节&#xff0c;决心开发一个新的脚本解释程序…

云表无代码开发平台,助力制造业练就数字化转型"硬功"

制造业作为国民经济的基础&#xff0c;也是我国的支柱产业&#xff0c;对我国经济发展具有重要意义。但随着近年来我国制造业转型升级步伐的加快&#xff0c;我国制造业在发展过程中也面临着许多困难和挑战。比如&#xff1a;企业生产设备老化、生产过程自动化程度低、产品质量…

Spark大数据处理讲课笔记3.3 掌握RDD分区

文章目录 零、本讲学习目标一、RRD分区&#xff08;一&#xff09;RDD分区概念&#xff08;二&#xff09;RDD分区作用 二、RDD分区数量&#xff08;一&#xff09;RDD分区原则&#xff08;二&#xff09;影响分区的因素&#xff08;三&#xff09;使用parallelize()方法创建RD…

【计算机视觉】Visual Transformer (ViT)模型结构以及原理解析

文章目录 一、简介二、Vision Transformer如何工作三、ViT模型架构四、ViT工作原理解析4.1 步骤1&#xff1a;将图片转换成patches序列4.2 步骤2&#xff1a;将patches铺平4.3 步骤3&#xff1a;添加Position embedding4.4 步骤4&#xff1a;添加class token4.5 步骤5&#xff…

数字图像处理--matlab图像反转、对数变换、伽马变换、对比度拉伸详解和代码实现

灰度变换在图像的单个像素上操作&#xff0c;主要以对比度和阈值处理为目的 空间滤波涉及改善性能的操作&#xff08;邻域操作&#xff09;&#xff0c;如通过图像中每一个像素的邻域处理来锐化图像 这两种方法均属于图像增强。 灰度变换 邻域基本增强变换定义数学表达三种基本…

QTableWidget表格控件的用法(非常详细)

QTableWidget表格控件的用法&#xff08;非常详细&#xff09; QTableWidget表格控件的用法&#xff08;非常详细&#xff09;QTableWidget详解1.常用API设置自动调整行高和列宽设置表格内容是否可编辑设置行表头、列表头是否显示 2.添加子项3.右键弹出菜单4.设置风格5.清空6.运…

LED灯内常见驱动电路

如今LED灯已成为照明的主流&#xff0c;使用白炽灯的家庭少之又少。其主要优势是LED灯更节能&#xff0c;相同光效的情况下&#xff0c;LED灯消耗的电能要比白炽灯减少70%以上。 LED灯的寿命比白炽灯要长&#xff0c;使用过白炽灯的人都知道&#xff0c;使用不了多长时间&…

简析Linux内核中的各种锁:信号量/互斥锁/读写锁/原子锁/自旋锁/内存屏障等

首先得搞清楚&#xff0c;不同锁的作用对象不同。 下面分别是作用于临界区、CPU、内存、cache 的各种锁的归纳&#xff1a; 一、atomic原子变量/spinlock自旋锁 — —CPU 既然是锁CPU&#xff0c;那就都是针对多核处理器或多CPU处理器。单核的话&#xff0c;只有发生中断会使…

生成C++工程的UML类图和类继承关系图

简介 在进行软件开发时&#xff0c;了解代码结构和关系、类之间的继承关系以及类内部的成员函数和变量定义是非常重要的。为此&#xff0c;我们可以使用Doxygen和Graphviz工具来生成UML类图和类集成关系图。 Doxygen是一个用于从注释的C源代码中生成文档的工具&#xff0c;支…

day01刷题记录

刷题 题目一分析题解 题目二分析题解 题目一 牛牛举办了一次编程比赛,参加比赛的有3*n个选手,每个选手都有一个水平值a_i.现在要将这些选手进行组队,一共组成n个队伍,即每个队伍3人.牛牛发现队伍的水平值等于该队伍队员中第二高水平值。 例如: 一个队伍三个队员的水平值分别是…

access数据库连接sqlserver实现远程连接

由于项目需要对接生产系统&#xff0c;但是生产系统使用的是access数据库&#xff08;这么老还在用&#xff0c;不知道咋想的&#xff09;&#xff0c;客户又想把项目部署到阿里云上&#xff0c;需要阿里云远程连接本地的access数据库&#xff08;心里一句MMP送上&#xff09;&…

Java——线程池详细讲解

文章目录 一、线程池一、线程池基础1.1 什么是线程池1.2 为什么使用线程池1.3 线程池有哪些优势1.4 应用场景 二、线程池使用2.1 Java内置线程池 ThreadPoolExecutor2.1.1 线程池的七个参数2.1.1.1 **int corePoolSize 核心线程数量**2.1.1.2 int maximumPoolSize 最大线程数2.…

假期后,野兔百科系统网站源码新版更新发布

这个是野兔百科系统中文版更新&#xff0c;这次更新了增加几个功能模块&#xff0c;几个已知的问题&#xff0c;修复系统部分功能。 系统名称&#xff1a;野兔百科系统 系统语言&#xff1a;中文版 系统源码&#xff1a;不加密&#xff0c;开源 系统开发&#xff1a;PHPMySQL …

尚融宝29-提现和还款

目录 一、提现 &#xff08;一&#xff09;需求 &#xff08;二&#xff09;前端 &#xff08;三&#xff09;后端 1、提现接口 2、回调接口 二、还款 &#xff08;一&#xff09;需求 &#xff08;二&#xff09;前端 &#xff08;三&#xff09;后端 1、还款接口 …