当前位置: 首页 > news >正文

牛客网面试必刷TOP101之——判断对称二叉树、求镜像二叉树与合并二叉树

⚓️作者简介:北京某能源高校非科班大四学生。

📚座右铭:“九层之台,起于垒土” 。所以学习技术须脚踏实地。

📖这里推荐一款刷题、模拟面试神器,可助你斩获大厂offer:点我免费刷题、模拟面试

文章目录

  • 前言
  • 面试必刷题
    • 1.对称的二叉树
    • 2.二叉树的镜像
    • 3.合并二叉树

前言

🌏牛客网是一个集笔面试系统、题库、课程教育、社群交流、招聘内推于一体的招聘类网站,更是一个专注于程序员的学习和成长的平台。

在某次浏览博客的过程中,我偶然点进一个链接,注册了牛客账号。一来到牛客首页,我就被其丰富的功能与良好的社区环境所吸引:
在这里插入图片描述
进入题库,更是有最新校招试题与专项练习:在这里插入图片描述
在线编程更是有在线调试功能,可大大提高debug效率:
在这里插入图片描述
问答题下还有超多牛客用户交流:
在这里插入图片描述
🔔总之,牛客是一个专注于程序员的学习和成长的平台,所以我极力推荐大家注册牛客,坚持刷题,充实自己,大厂offer便指日可待。

面试必刷题

 二叉树(Binary tree)是树形结构的一个重要类型。许多实际问题抽象出来的数据结构往往是二叉树形式,即使是一般的树也能简单地转换为二叉树,而且二叉树的存储结构及其算法都较为简单,因此二叉树显得特别重要。上一节我们练习了二叉树的层序遍历与二叉树转换为双向链表,这一节来刷几个进阶点的题目:

📚

1.对称的二叉树

题目:
在这里插入图片描述

示例:
在这里插入图片描述

解题思路
这题应该可以用递归写,但上周刷题用的方法大多都是通过队列或栈处理二叉树,所以这题就继续用栈与队列处理。

类比于二叉树的层序遍历,这题也可以利用层序遍历来解,只不过要改变每层的遍历顺序。每次遍历遍历对称的两个节点,判断其左右结构是否对称,再判断值是否对称,若都满足,则当前节点及其父节点都是对称的。

算法流程:

  • 对于根节点特殊处理:根节点为空,则是对称的。不空判断左右孩子是否对称,对称则将左右孩子入栈;不对称则该树不对称。

  • 栈不空,进入循环1。

    • 栈不空,进入循环2。
    • 连着两个节点出栈,分别保存为node1,node2(根据进队结点的性质,这两个结点是对称结点)。
    • 先判断两个节点结构是否对称,即node1有右孩子同时node2有左孩子,或node1有左孩子同时node2有右孩子。对称则判断数值是否相等,相等则将node1的右孩子,node2的左孩子连续进队,或node2的右孩子,node1的左孩子连续进队。不对称则该树不对称。
    • 回到循环2。
  • 将 q 中的节点出队并进栈,回到循环1。

C++解题代码:


/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};
*/
class Solution {
  public:
    bool isSymmetrical(TreeNode* pRoot) {
        if (!pRoot || (!pRoot->left && !pRoot->right)) return true;
        if (!pRoot->left || !pRoot->right) return false;
        stack<TreeNode*> s;
        if (pRoot->left->val == pRoot->right->val) {
            s.push(pRoot->left);
            s.push(pRoot->right);
        } else
            return false;
        queue<TreeNode*> q;
        while (!s.empty()) {
            while (!s.empty()) {
                TreeNode* node1 = s.top();
                s.pop();
                if (s.empty())return false;
                TreeNode* node2 = s.top();
                s.pop();
                if (((node1->left && node2->right) || (!node1->left && !node2->right)) &&
                        (node1->right && node2->left || (!node1->right && !node2->left))) {
                    if (node1->left && node2->right) {
                        if (node1->left->val == node2->right->val) {
                            q.push(node1->left);
                            q.push(node2->right);
                        } else return false;
                    }
                    if (node1->right && node2->left) {
                        if (node1->right->val == node2->left->val) {
                            q.push(node1->right);
                            q.push(node2->left);
                        } else return false;
                    }
                }else return false;
            }
            while(!q.empty()) {
                TreeNode* node;
                node = q.front();
                q.pop();
                s.push(node);
            }

        }
        return true;

    }

};

2.二叉树的镜像

题目:
在这里插入图片描述

示例:
在这里插入图片描述

解题思路
这一题就是利用前序遍历交换两个结点即可,每交换两个结点,结点包括结点的左右孩子也都交换了。递归地交换,即可求得整个二叉树的镜像。

算法流程:

  1. 特殊情况:如果pRoot为空,返回空
  2. 交换左右子树
  3. 把pRoot的左子树镜像一下
  4. 把pRoot的右子树镜像一下
  5. 返回根节点root

C++解题代码:

/**
 * struct TreeNode {
 *  int val;
 *  struct TreeNode *left;
 *  struct TreeNode *right;
 *  TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 * };
 */
class Solution {
  public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param pRoot TreeNode类
     * @return TreeNode类
     */
    TreeNode* Mirror(TreeNode* pRoot) {
        mirror(pRoot);
        return pRoot;
    }
  private:
    void mirror(TreeNode* pRoot) {
        if (!pRoot) return;
        TreeNode* tmp = pRoot->right;
        pRoot->right = pRoot->left;
        pRoot->left = tmp;
        mirror(pRoot->right);
        mirror(pRoot->left);
    }
};

3.合并二叉树

题目:
在这里插入图片描述

示例:

在这里插入图片描述

解题思路:
要将一棵二叉树的节点与另一棵二叉树相加合并,肯定需要遍历两棵二叉树,那我们可以考虑同步遍历两棵二叉树,这样就可以将每次遍历到的值相加在一起。遍历的方式有多种,这里推荐前序递归遍历。

算法步骤:

  • 以第一个t1为返回树,相加的值存入tree1。

  • 如果node1和node2为空,则返回空指针。

  • 如果node1不空,node2空,返回node1。

  • 如果node1空,node2不空,返回node2。

  • 如果都不空则将两个结点值相加存到node1的值中,再merge两棵树的左右子树。

C++解题代码

/**
 * struct TreeNode {
 *	int val;
 *	struct TreeNode *left;
 *	struct TreeNode *right;
 * };
 */

class Solution {
public:
    /**
     * 
     * @param t1 TreeNode类 
     * @param t2 TreeNode类 
     * @return TreeNode类
     */
    TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) {
        // write code here
        TreeNode *node1 = t1, *node2 = t2;
        return merge(node1, node2);
    }
private:
    TreeNode* merge(TreeNode* node1, TreeNode* node2){
        if(!node1 && !node2) return nullptr;
        if(!node1 && node2) return node2;
        if(node1 && !node2) return node1;
        node1->val += node2->val;
        node1->left = merge(node1->left, node2->left);
        node1->right = merge(node1->right, node2->right);
        return node1;
    }
};

🥇我希望通过写博客来结束浑浑噩噩的生活,我更希望通过刷题结束人云亦云的思考。刷题不仅仅是刷题,还是我们与自己内心深处的对话。希望我们可以一起在牛客刷题交流,一起收割大厂offer!

相关文章:

  • JavaSE笔记(二)重制版
  • 【LabVIEW专题】LabVIEW 通过串口进行Modbus协议通信
  • 软件分享-
  • java扶贫平台计算机毕业设计MyBatis+系统+LW文档+源码+调试部署
  • 十年数据库专家,呕心力作MySQL技术精粹,薪资直涨3K其实很轻松
  • D. Empty Graph #813 div2
  • 02 NLP合集-神经网络从0开始推理-一个间的神经网路的预测-没有backforward的情况下
  • 驱动程序开发:SPI设备驱动
  • PostgreSQL - 基于pg_basebackup实现主从流复制
  • Java项目源码ssm+mysql实现进销存系统|仓库
  • 黑马瑞吉外卖之套餐信息的分页查询
  • 9.14 c++基础
  • python创建智能问答机器人
  • MyBatis的简介和核心的组件(映射器、执行器、SqlSession及其工厂)
  • 《计算几何》学习笔记
  • 【css3】浏览器内核及其兼容性
  • 【个人向】《HTTP图解》阅后小结
  • 11111111
  • C语言笔记(第一章:C语言编程)
  • Django 博客开发教程 16 - 统计文章阅读量
  • Java IO学习笔记一
  • Java的Interrupt与线程中断
  • Nginx 通过 Lua + Redis 实现动态封禁 IP
  • React+TypeScript入门
  • Redis 中的布隆过滤器
  • 道格拉斯-普克 抽稀算法 附javascript实现
  • 官方解决所有 npm 全局安装权限问题
  • 前端面试总结(at, md)
  • 思否第一天
  • 为视图添加丝滑的水波纹
  • 线上 python http server profile 实践
  • 在 Chrome DevTools 中调试 JavaScript 入门
  • 正则表达式-基础知识Review
  • # Swust 12th acm 邀请赛# [ K ] 三角形判定 [题解]
  • (6)添加vue-cookie
  • (十五)devops持续集成开发——jenkins流水线构建策略配置及触发器的使用
  • (学习日记)2024.01.09
  • (原創) 如何解决make kernel时『clock skew detected』的warning? (OS) (Linux)
  • **登录+JWT+异常处理+拦截器+ThreadLocal-开发思想与代码实现**
  • .bat批处理(一):@echo off
  • .NET Standard 的管理策略
  • .NET精简框架的“无法找到资源程序集”异常释疑
  • @AliasFor注解
  • @Data注解的作用
  • @WebService和@WebMethod注解的用法
  • [ vulhub漏洞复现篇 ] Django SQL注入漏洞复现 CVE-2021-35042
  • []C/C++读取串口接收到的数据程序
  • []使用 Tortoise SVN 创建 Externals 外部引用目录
  • [autojs]逍遥模拟器和vscode对接
  • [C++] Windows中字符串函数的种类
  • [caffe(二)]Python加载训练caffe模型并进行测试1
  • [CC2642r1] ble5 stacks 蓝牙协议栈 介绍和理解
  • [Django开源学习 1]django-vue-admin
  • [I2C]I2C通信协议详解(二) --- I2C时序及规格指引
  • [LeetCode] 197. 上升的温度