2021-11-05每日刷题打卡

2021-11-05每日刷题打卡

力扣 ——二叉树

剑指 Offer II 044. 二叉树每层的最大值515. 在每个树行中找最大值

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

示例1:

输入: root = [1,3,2,5,3,null,9]
输出: [1,3,9]
解释:
1
/
3 2
/ \ \
5 3 9

层序遍历二叉树,每次遍历新的一层时准备一个max来存最大值,然后依次比较,遍历完后把max存入vector容器中,然后继续遍历下一层。

/**
 * 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) {
        vector<int>v;
        if(!root)return v;
        queue<TreeNode*>que;
        que.push(root);
        while(que.size())
        {
            int len=que.size();
            int max=que.front()->val;
            for(int i=0;i<len;i++)
            {
                if(max<que.front()->val)max=que.front()->val;
                if(que.front()->left)que.push(que.front()->left);
                if(que.front()->right)que.push(que.front()->right);
                que.pop();
            }
            v.push_back(max);
        }
        return v;
    }
};
617. 合并二叉树

给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。

你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接作为新二叉树的节点。

示例 1:

输入:
Tree 1 Tree 2
1 2
/ \ / \
3 2 1 3
/ \ \
5 4 7
输出:
合并后的树:
3
/
4 5
/ \ \
5 4 7
注意: 合并必须从两个树的根节点开始。

先判断一下,如果root1为空而root2不为空那就返回root2即可,反之返回root1,如果两个都空那么返回哪个都行,如果两个都不为空那我们就开始合并的操作。直接把两个树传入dfs里,我们以root1为主树,dfs的实现是,先判断root2是否为空,如果为空就直接结束程序,如果root2不为空而root1为空,那就直接让root1=root2,以此获得root2的当前结点和之后所有节点(记住dfs的参数传递要以引用的方式才行),如果两个都不为空,那就把root2的val值加到root1上,然后再分别把root1和root2的左子节点和右子节点传入dfs里。当递归结束后root1就是合并后的二叉树了。

/**
 * 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&&!root2)return root1;
        else if(!root1&&root2)return root2;
        else if(!root2&&root1)return root1; 
        dfs(root1,root2);
        return root1;
    }
    void dfs(TreeNode*&p,TreeNode*&q)
    {
        if(!q)return;
        else if(!p&&q)
        {

            p=q;
            return;
        }
        p->val+=q->val;
        dfs(p->left,q->left);
        dfs(p->right,q->right);
    }
};
105. 从前序与中序遍历序列构造二叉树

给定一棵树的前序遍历 preorder 与中序遍历 inorder。请构造二叉树并返回其根节点。

示例 1:

tree.jpg (277×302) (leetcode.com)

Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
Output: [3,9,20,null,null,15,7]

这题感觉太复杂了想着一开始先写个大概出来等有错了一步步改,结果一写完发现通过测试例了,整个人疑惑了一下然后点了下提交就这么直接过了也太爽了!还有什么比这更爽的事情吗?

前序遍历的结构组成是:(根节点)(左子树)(右子树) 中序遍历的结构组成是:(左子树)(根节点)(右子树)

那么我们就可以发现了,前序遍历的开头必是根节点,然后我们拿根节点在中序遍历里找,左边就是左子树的序列,右边就是右子树的序列,然后我们再回到前序遍历里找左子树,找到的第一个就是左子树的根节点,然后再拿这个根节点回到中序遍历里找…………以此循环往复,中途每次找到根节点就把它和父节点连起来最后得到的就是整个树的样子了。

/**
 * 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* buildTree(vector<int>& preorder, vector<int>& inorder) {
        return dfs(preorder,inorder);
    }
    TreeNode* dfs(vector<int>p,vector<int>q)
    {
        if(!p.size())return NULL;
        TreeNode *root;
        root=new TreeNode(p[0]);
        int n=q.size();
        vector<int>v1;
        vector<int>v2;
        vector<int>v3;
        vector<int>v4;
        int j;
        for(int i=0;i<n;i++)
        {
            if(q[i]==p[0])
            {
                j=i;
                break;
            }
            v1.push_back(p[i+1]);
            v2.push_back(q[i]);
        }
        for(int i=j+1;i<n;i++)
        {
            v3.push_back(p[i]);
            v4.push_back(q[i]);
        }
        root->left=dfs(v1,v2);
        root->right=dfs(v3,v4);
        return root;
    }
};
106. 从中序与后序遍历序列构造二叉树

根据一棵树的中序遍历与后序遍历构造二叉树。

注意:
你可以假设树中没有重复的元素。

例如,给出

中序遍历 inorder = [9,3,15,20,7]
后序遍历 postorder = [9,15,7,20,3]
返回如下的二叉树:

3

/
9 20
/
15 7

这题和前面的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* buildTree(vector<int>& inorder, vector<int>& postorder) {
        return dfs(inorder,postorder);
    }
    TreeNode* dfs(vector<int>p,vector<int>q)
    {
        if(!q.size())return NULL;
        vector<int>v1;
        vector<int>v2;
        vector<int>v3;
        vector<int>v4;
        TreeNode *root;
        int n=q.size(),j;
        root =new TreeNode(q[n-1]);
        for(int i=0;i<n;i++)
        {
            if(p[i]==q[n-1])
            {
                j=i;
                break;
            }
            v1.push_back(p[i]);
            v2.push_back(q[i]);
        }
        for(int i=j+1;i<n;i++)
        {
            v3.push_back(p[i]);
            v4.push_back(q[i-1]);
        }
        root->left=dfs(v1,v2);
        root->right=dfs(v3,v4);
        return root;
    }
};
199. 二叉树的右视图

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

示例 1:

tree.jpg (401×301) (leetcode.com)

输入: [1,2,3,null,5,null,4]
输出: [1,3,4]

这题目前能想到简单点的方法就是层序遍历,层序遍历完后把每层的最后一个数存入vector中,最后返回那个vector。(注意一开始要判断root是否为空,如果为空就返回一个空的vector容器给它)

/**
 * 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>>v1;
    vector<int>v;
    vector<int> rightSideView(TreeNode* root) {
        if(!root)return v;
        dfs(root,0);
        for(int i=0;i<v1.size();i++)
        {
            v.push_back(v1[i][v1[i].size()-1]);
        }
        return v;
    }
    void dfs(TreeNode*root,int u)
    {
        if(!root)return;
        if(v1.size()<u+1)
        {
            vector<int>v2;
            v1.push_back(v2);
        }
        v1[u].push_back(root->val);
        dfs(root->left,u+1);
        dfs(root->right,u+1);
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值