二叉树专题(一)

104. 二叉树的最大深度

给定一个二叉树 root ,返回其最大深度。

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

class Solution {
public:
    int maxDepth(TreeNode* root) {
        if(!root){
            return 0;
        }
        return max(maxDepth(root->left),maxDepth(root->right))+1;
    }
};

543.二叉树的直径

给你一棵二叉树的根节点,返回该树的 直径 。

二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 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:
    int diameter=0;
    int Maxdeepth(TreeNode* t){
        if(!t){
            return 0;
        }
        int l=Maxdeepth(t->left);
        int r=Maxdeepth(t->right);
        diameter=max(diameter,l+r);
        return max(l,r)+1;
    }
    int diameterOfBinaryTree(TreeNode* root) {
        Maxdeepth(root);
        return diameter;
    }
};

 

114. 二叉树展开为链表

给你二叉树的根结点 root ,请你将它展开为一个单链表:

  • 展开后的单链表应该同样使用 TreeNode ,其中 right 子指针指向链表中下一个结点,而左子指针始终为 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:
    void flatten(TreeNode* root) {
        if(!root){return;}
        //将左右子树拉平
        flatten(root->left);
        flatten(root->right);
        TreeNode* left=root->left;
        TreeNode* right=root->right;
        root->left=nullptr;
        root->right=left;//将左子树作为右子树
        TreeNode* p=root;
        while(p->right){
            p=p->right;
        }
        p->right=right;//将原先的右子树接到当前右子树末端
    }
};

 

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:
    //抽象成三叉树
    void traverse(Node* n1,Node* n2){
        if(n1==nullptr||n2==nullptr){return;}
        n1->next=n2;
        traverse(n1->left,n1->right);
        traverse(n1->right,n2->left);
        traverse(n2->left,n2->right);
    }
    Node* connect(Node* root) {
        if(!root){return nullptr;}
        traverse(root->left,root->right);
        return root;
    }
};

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

给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。

 

 思路:先构造根节点,再递归构造左右子树

/**
 * 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:
    map<int,int> h;
    TreeNode* build(vector<int>& preorder,int prestart,int preend, vector<int>& inorder,int instart,int inend){
        if(prestart>preend){return nullptr;}
        int rootval=preorder[prestart];// root节点对应的值就是前序遍历数组的第一个元素
        int index=h[rootval];//rootval在中序遍历数组中的索引
        TreeNode* root=new TreeNode(rootval);
        int leftsize=index-instart;
        //递归构造左右子树
        root->left=build(preorder,prestart+1,prestart+leftsize,inorder,instart,index-1);
        root->right=build(preorder,prestart+leftsize+1,preend,inorder,index+1,inend);
        return root;
    }
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        for(int i=0;i<inorder.size();i++){
            h[inorder[i]]=i;
        }
        return build(preorder,0,preorder.size()-1,inorder,0,inorder.size()-1);

    }
};

 

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

给定两个整数数组 inorder 和 postorder ,其中 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:
    map<int,int> h;
    TreeNode* build(vector<int>& inorder, int inStart,int inEnd,
                    vector<int>& postorder,int postStart,int postEnd){
                        if(inStart>inEnd){return nullptr;}
                        int rootVal=postorder[postEnd];
                        int index=h[rootVal];
                        TreeNode* root=new TreeNode(rootVal);
                        int leftSize=index-inStart;
                        root->left=build(inorder,inStart,index-1,
                                         postorder,postStart,postStart+leftSize-1);
                        root->right=build(inorder,index+1,inEnd,
                                         postorder,postStart+leftSize,postEnd-1);
                        return root;
                    }
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        for(int i=0;i<inorder.size();i++){
            h[inorder[i]]=i;
        }
        return build(inorder,0,inorder.size()-1,postorder,0,postorder.size()-1);
    }
};

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* build(vector<int>& nums,int low,int high){
        if(low>high){
            return nullptr;
        }
        int index=-1,maxval=INT_MIN;//maxval最大值 index最大值的数组下标
        for(int i=low;i<=high;i++){
            if(nums[i]>maxval){
                maxval=nums[i];
                index=i;
            }
        }
        TreeNode* root=new TreeNode(maxval);
        //递归
        root->left=build(nums,low,index-1);
        root->right=build(nums,index+1,high);
        return root;
    }
    TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
        return build(nums,0,nums.size()-1);
    }
};

652. 寻找重复的子树

给你一棵二叉树的根节点 root ,返回所有 重复的子树 

对于同一类的重复子树,你只需要返回其中任意 一棵 的根结点即可。

如果两棵树具有 相同的结构 和 相同的结点值 ,则认为二者是 重复 的。

思路:将一颗树的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:
    unordered_map<string,int> h;
    vector<TreeNode*> res;
    string  DFS(TreeNode* root){
        if(root==nullptr){
            return "";
        }
        string s=to_string(root->val)+"#"+DFS(root->left)+"#"+DFS(root->right);//将一颗树的val取出形成字符串序列
        h[s]++;
        if(h[s]==2){
            res.push_back(root);
        }
        return s;
    }
    vector<TreeNode*> findDuplicateSubtrees(TreeNode* root) {
        DFS(root);
        return res;
    }
};

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值