【算法训练-二叉树 四】【对称与翻转】对称二叉树、翻转二叉树

2023-09-21 22:16:13

废话不多说,喊一句号子鼓励自己:程序员永不失业,程序员走向架构!本篇Blog的主题是【二叉树的形态变化】,使用【二叉树】这个基本的数据结构来实现,这个高频题的站点是:CodeTop,筛选条件为:目标公司+最近一年+出现频率排序,由高到低的去牛客TOP101去找,只有两个地方都出现过才做这道题(CodeTop本身汇聚了LeetCode的来源),确保刷的题都是高频要面试考的题。
在这里插入图片描述

名曲目标题后,附上题目链接,后期可以依据解题思路反复快速练习,题目按照题干的基本数据结构分类,且每个分类的第一篇必定是对基础数据结构的介绍

对称二叉树【EASY】

对称二叉树的判断

题干

在这里插入图片描述

解题思路

对称,就是左右两边相等,也就是左子树和右子树是相当的注意这句话,左子树和右子相等,也就是说要递归的比较左子树和右子树。
我们将根节点的左子树记做 left,右子树记做 right。

  • 比较 left 是否等于 right,不等的话直接返回就可以了。
  • 如果相当,比较 left 的左节点和 right 的右节点,再比较 left 的右节点和 right 的左节点
    比如看下面这两个子树(他们分别是根节点的左子树和右子树),能观察到这么一个规律

在这里插入图片描述

  • 终止条件: 当进入子问题的两个节点都为空,说明都到了叶子节点,且是同步的,因此结束本次子问题,返回true;当进入子问题的两个节点只有一个为空,或是元素值不相等,说明这里的对称不匹配,同样结束本次子问题,返回false。
  • 返回值: 每一级将子问题是否匹配的结果往上传递。
  • 本级任务: 每个子问题,需要按照上述思路,“根左右”走左边的时候“根右左”走右边,“根左右”走右边的时候“根右左”走左边,一起进入子问题,需要两边都是匹配才能对称

代码实现

给出代码实现基本档案

基本数据结构二叉树
辅助数据结构
算法递归、DFS
技巧

其中数据结构、算法和技巧分别来自:

  • 10 个数据结构:数组、链表、栈、队列、散列表、二叉树、堆、跳表、图、Trie 树
  • 10 个算法:递归、排序、二分查找、搜索、哈希算法、贪心算法、分治算法、回溯算法、动态规划、字符串匹配算法
  • 技巧:双指针、滑动窗口、中心扩散

当然包括但不限于以上

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param pRoot TreeNode类
     * @return bool布尔型
     */
    public boolean isSymmetrical (TreeNode pRoot) {
        if (pRoot == null) {
            return true;
        }
        return dfsCheck(pRoot.left, pRoot.right);
    }

    private boolean dfsCheck(TreeNode left, TreeNode right) {
        // 1 递归终止条件:如果左右子节点都为null,说明到达叶子节点,终止且为true
        if (left == null && right == null) {
            return true;
        }

        // 2 本级判断依据:如果两个节点其中一个为null则不对称
        if (left == null || right == null) {
            return false;
        }
        // 3 本级判断依据:如果两个节点值不相等,则不对称
        if (left.val != right.val) {
            return false;
        }

        // 4 继续进入下级做判断
        return dfsCheck(left.right, right.left) && dfsCheck(left.left, right.right);
    }
}

复杂度分析

时间复杂度:O(n),其中n为二叉树的节点数,遍历整棵二叉树
空间复杂度:O(n),最坏情况下,二叉树化为链表,递归栈深度最大为n

翻转二叉树【EASY】

和对称二叉树类似,只不过对称二叉树是判断,翻转二叉树是做节点位移

题干

在这里插入图片描述

解题思路

其实就是交换一下左右节点,然后再递归的交换左节点,右节点我们可以总结出递归的两个条件如下:

  • 终止条件:当前节点为 null 时返回
  • 交换当前节点的左右节点,再递归的交换当前节点的左节点,递归的交换当前节点的右节点

深度优先遍历。

代码实现

给出代码实现基本档案

基本数据结构二叉树
辅助数据结构
算法递归,DFS
技巧

其中数据结构、算法和技巧分别来自:

  • 10 个数据结构:数组、链表、栈、队列、散列表、二叉树、堆、跳表、图、Trie 树
  • 10 个算法:递归、排序、二分查找、搜索、哈希算法、贪心算法、分治算法、回溯算法、动态规划、字符串匹配算法
  • 技巧:双指针、滑动窗口、中心扩散

当然包括但不限于以上

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param pRoot TreeNode类
     * @return TreeNode类
     */
    public TreeNode Mirror (TreeNode pRoot) {
        if (pRoot == null) {
            return null;
        }
        dfsChange(pRoot);
        return pRoot;

    }

    private TreeNode dfsChange(TreeNode node) {
        // 1 递归终止条件:节点为null
        if (node == null) {
            return null;
        }

        // 2 本级任务,交换 左右子树
        TreeNode temp = node.left;
        node.left = node.right;
        node.right = temp;

        // 3 递归交换左右子树内部结构
        dfsChange(node.left);
        dfsChange(node.right);

        return node;
    }
}

复杂度分析

时间复杂度:遍历了整棵树节点,时间复杂度为O(N)
空间复杂度:极端情况下,二叉树退化为链表,递归栈的深度为O(N),空间复杂度为O(N)

更多推荐

急救车工业路由器应用提升急救效率:车联网、数据采集与远程诊疗

急救车作为医院里医疗急救过程中的重要组成部分,在智慧医疗物联网领域中急救车应用4G工业路由器实现网络部署与数据采集,通过工业4G路由器能够实时采集到病患的生理数据、救护现场音频与视频、GPS定位以及车辆运行状态等重要信息。这些数据将被传输到医疗急救系统帮助院内医生对急救车上的病患进行初步判断,并及时提供远程诊疗协助。I

【计算机网络】图解路由器(一)

图解路由器(一)1、什么是路由器?2、什么是路由选择?3、什么是转发?4、路由器设备有哪些类型?5、根据性能分类,路由器有哪些类型?5.1高端路由器5.2中端路由器5.3低端路由器6、什么是家用路由器?7、运营商用什么类型的路由器?8、企业用什么类型的路由器?9、什么是IP地址?10、地址如何分类?11、什么是CIDR

浅谈C++|文件篇

引子:程序运行时产生的数据都属于临时数据,程序一旦运行结束都会被释放通过文件可以将数据持久化。C++中对文件操作需要包含头文件<fstream>。C++提供了丰富的文件操作功能,你可以使用标准库中的fstream库来进行文件的读取、写入和定位等操作。文件操作在许多应用中非常常见,例如读取配置文件、处理日志、存储数据等。

oracle的正则表达式(regular expression)

当前,正则表达式已经在很多软件中得到广泛的应用,包括Linux,Unix,HP等操作系统,PHP,C#,Java等开发环境,ORACLE则在10G中推出了自己的正则表达式。Oracle10g正则表达式提高了SQL灵活性,有效的解决了数据有效性,重复词的辨认,无关的空白检测,或者分解多个正则组成的字符串等问题。Oracl

服务器性能测试监控平台export+prometheus(普罗米修斯)+grafana搭建

1.export数据采集工具简介:export是prometheus是的数据采集组件的总称,它可以将采集到的数据转为prometheus支持的格式node_export:用来监控服务器硬件资源的采集器,端口号为9100mysql_export:用来监控mysql数据库资源的采集器,端口号是91042.prometheu

【翻译】Kingfisher 官方指南 Cheet Sheet

原文地址:https://github.com/onevcat/Kingfisher/wiki/Cheat-SheetThisdocumentationwilldescribesomemostcommonusageofKingfisher.ThecodesnippetisbasedoniOS.However,thesi

云原生Kubernetes:pod进阶之资源管理与探针

目录一、理论1.pod的资源限制2.健康检查(探针Probe)3.示例二、实验1.pod的资源限制2.健康检查(探针Probe)三、问题1.生成资源报错2.api版本错误3.echoN>/proc/sys/vm/drop_caches如何实现清理缓存4.生成启动退出容器报错5.如何完全清除日志四、总结一、理论1.pod

Qt事件处理

1.事件众所周知Qt是一个基于C++的框架,主要用来开发带窗口的应用程序(不带窗口的也行,但不是主流)。我们使用的基于窗口的应用程序都是基于事件,其目的主要是用来实现回调(因为只有这样程序的效率才是最高的)。所以在Qt框架内部为我们提供了一些列的事件处理机制,当窗口事件产生之后,事件会经过:事件派发->事件过滤->事件

软件工程开发模式:从传统到现代的演进

引言软件工程开发模式是指导软件开发过程的重要框架,旨在提高软件开发的效率和质量。随着技术的不断进步,软件工程开发模式也在不断发展演变,以适应不同的项目需求和开发环境。本文将介绍传统软件工程开发模式和现代敏捷、精益和DevOps软件工程开发模式,以及云计算背景下的软件工程开发模式。传统软件工程开发模式传统软件工程开发模式

【FAQ】安防监控视频云存储平台EasyNVR对接EasyNVS时,一直不上线该如何解决?

视频安防监控平台EasyNVR可支持设备通过RTSP/Onvif协议接入,并能对接入的视频流进行处理与多端分发,包括RTSP、RTMP、HTTP-FLV、WS-FLV、HLS、WebRTC等多种格式。近期有用户在使用安防视频平台EasyNVR对接上级平台EasyNVS时,出现了一直不上线的情况。为给用户带来最优体验,技

计算机毕业设计 基于SSM+Vue的物资存储系统(以消防物资为例)的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍:✌从事软件开发10年之余,专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌🍅文末获取源码联系🍅👇🏻精彩专栏推荐订阅👇🏻不然下次找不到哟————————————————计算机毕业设计题目《10

热文推荐