LeetCode 101. 对称二叉树 思考分析

题目

给定一个二叉树,检查它是否是镜像对称的。

例如,二叉树 [1,2,2,3,4,4,3] 是对称的。

1

/
2 2
/ \ /
3 4 4 3

但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的:

1

/
2 2
\
3 3

进阶:
你可以运用递归和迭代两种方法解决这个问题吗?

思路一,超时

层序遍历,然后如果该结点是空结点,往该层子数组中填0,否则填val;
当此层所有结点都被遍历了(包括空结点),观察子数组是否对称。
然后更新queue,如果该结点为空结点,则它的子结点也是空结点,如果该结点不是空结点,它的子结点根据真实情况填,如果为空也填入NULL。
不过这样好像超时了,也就无法验证了。
退出循环的条件是,该层的所有结点都是空结点

/*** 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:bool isSymmetric(TreeNode* root) {queue<TreeNode*> que;if(root!=NULL) que.push(root);while(1){//该层结点元素个数 = 该层队列元素int size = que.size();vector<int> vec;int null_times=0;//这里要使用固定大小的size,不能使用que.size(),因为在处理中que.size是不断变化的//将这层元素送入队列中并依次从队首向队尾将元素出队列,每个元素出队列的同时又将其不为空的子结点送入队列for(int i =0;i<size;i++){TreeNode* node = que.front();//将队首元素送入该层结果que.pop();if(node!=NULL) {vec.push_back(node->val);//将左右孩子结点入队列,作为下一层的元素if(node->left!=NULL) que.push(node->left);else que.push(NULL);if(node->right!=NULL) que.push(node->right);else que.push(NULL);}else{null_times++;vec.push_back(-2147483648);//将左右孩子结点入队列,作为下一层的元素que.push(NULL);que.push(NULL);} }if(null_times == size) break;int vecsize=vec.size();for(int j=0;j<vecsize/2+1;j++){if(vec[j]!=vec[vecsize-1-j]) return false;}}return true;}
};

思路二,构造翻转二叉树,判断是否相同

先构造一棵反转二叉树,然后按顺序遍历这两棵树,判断是否相同。
Leetcode226. 翻转二叉树(递归、迭代、层序三种解法)
LeetCode 100. 相同的树 思考分析
不过此处有一个问题,我们当时翻转二叉树的操作是在输入的二叉树上进行修改的。这样如果直接isSameTree(root,invertTree(root));
得到的结果都是true。所以我们需要先深复制一个新的二叉树,然后在新的二叉树上完成翻转操作,然后将翻转后的二叉树与原本的二叉树进行判断。
关于深复制一棵二叉树:
LintCode 375. 克隆二叉树(深复制)

/*** 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* invertTree(TreeNode* root) {queue<TreeNode*> que;if(root!=NULL) que.push(root);while(!que.empty()){int size = que.size();for(int i =0;i<size;i++){TreeNode* node = que.front();que.pop();TreeNode* tmp;tmp = node->left;node->left = node->right;node->right = tmp;//将左右孩子结点入队列,作为下一层的元素if(node->left) que.push(node->left);if(node->right) que.push(node->right);}}return root;}bool isSameTree(TreeNode* p, TreeNode* q) {if(p && q){if(p->val == q->val){return isSameTree(p->right,q->right) && isSameTree(p->left,q->left);}else{return false;} }else if(!p && !q){return true;}return false;}TreeNode * preorder(TreeNode * root){if(root==NULL) return NULL;TreeNode * ans;ans=new TreeNode(root->val);if(root->left!=NULL){ans->left=preorder(root->left);}if(root->right!=NULL){ans->right=preorder(root->right);}return ans;}bool isSymmetric(TreeNode* root) {TreeNode *roota;roota=preorder(root);return isSameTree(root,invertTree(roota));}
};

在这里插入图片描述

参考其他思路

之前的构造的思路会导致空间严重浪费,并且时间耗费也较多。
关于二叉树是否对称,我们要比较的是根结点的左子树与右子树是不是相互翻转的。递归遍历的时候要同时遍历两棵树,比较两棵子树的里侧和外侧元素是否相同
本题的遍历顺序为后序遍历,因为要通过递归函数的返回值来判断两个子树的内测结点与外侧结点是否相等。
一棵树遍历顺序为左右中,另一棵树遍历顺序是右左中。这里可以理解为一种回溯的思想。

递归法

1、确定递归地参数和返回值
参数:该结点的左子树结点、右子树结点
返回值:bool类型
bool compare(TreeNode* left,TreeNode* right)
2、确定终止条件
1、左右都为空,返回true
2、左右只有一个为空,返回false
3、左右结点均不为空,比较结点数值,不相同返回false
4、左右结点均不为空,数值相同返回true

if(left == NULL && right==NULL) return true;
else if(left!=NULL && right==NULL) return false;
else if(right!=NULL && left==NULL) return false;
else if(left->val != right->val) return false;

3、确定单层递归逻辑
处理左右结点皆不为空且数值相同的情况。
1、比较二叉树外侧是否对称:传入左结点的左孩子,右结点的右孩子。
2、比较内侧是否对称,传入左结点的右孩子,右结点的左孩子。
3、如果左右都对称就返回true,否则返回false

bool outside = compare(left->left,right->right);	
bool inside = compare(left->right,right->left);
bool isSame = outside && inside;		
return isSame

完整代码

/*** 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:bool compare(TreeNode* left,TreeNode* right){if(left == NULL && right==NULL) return true;else if(left!=NULL && right==NULL) return false;else if(right!=NULL && left==NULL) return false;else if(left->val != right->val) return false;bool outside = compare(left->left,right->right);	bool inside = compare(left->right,right->left);bool isSame = outside && inside;		return isSame;}bool isSymmetric(TreeNode* root) {if(root == NULL) return true;return compare(root->left,root->right);}
};

在这里插入图片描述

迭代法

这一题的本质是判断两个树是否相互翻转,并非简单的遍历。这里可以使用队列来比较两个树(根结点的左右子树)是否相互翻转。

/*** 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:bool isSymmetric(TreeNode* root) {if(root == NULL) return true;queue<TreeNode*> que;que.push(root->left);       //将左子树头结点加入队列que.push(root->right);      //将右子树头结点加入队列while(!que.empty())         //判断两个树是否翻转{TreeNode* leftNode = que.front();que.pop();TreeNode* rightNode = que.front();que.pop();if(!leftNode && !rightNode) {//左右结点均为空,说明此时是对称的continue;}//左右一个结点不为空,或者都不为空但是数值不同,返回falseif((!leftNode || !rightNode || (leftNode->val!=rightNode->val))){return false;}//外侧que.push(leftNode->left);   //左左que.push(rightNode->right); //右右//内侧que.push(leftNode->right);que.push(rightNode->left);}return true;}
};

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

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

相关文章

内心能不能宁静一点,做事能不能坚持一下

内心能不能宁静一点&#xff0c;做事能不能坚持一下 每次朋友问我怎么样&#xff0c;我总感觉不好回答&#xff0c;如果说实话我想他们或许是不能理解我的处境的&#xff0c;只能报以“还好”之类的语言&#xff0c;糊弄一下。唯一一次说了实话是&#xff1a;我坠落了&#xff…

直方图反向投影

通过直方图反向投影&#xff0c;根据目标衣服颜色的特征来进行定位 cv2.calcHist([roi_hsv],[0,1],None,[32,48],[0,180,0,256])其中[32,48]表示bin的个数&#xff0c;可以修改&#xff0c;当然范围越小越精确 import cv2 import numpy as np from matplotlib import pyplot …

javascript 排序_JavaScript中的排序方法

javascript 排序There are tons of sorting algorithms available like bubble sort, merge sort, insertion sort etc. You must have implemented some of these in other programming languages like C or C. But in this article, I will be demonstrating the Sorting met…

LeetCode 二叉树、N叉树的最大深度与最小深度(递归解)

目录104. 二叉树的最大深度559. N叉树的最大深度111. 二叉树的最小深度之前的笔记中&#xff0c;已经用层序遍历解决过这个问题了现在试着用深度的解法去求解104. 二叉树的最大深度 给定一个二叉树&#xff0c;找出其最大深度。 二叉树的深度为根节点到最远叶子节点的最长路径…

十、模板匹配

一、概念 模板匹配就是在整个图像区域发现与给定子图像匹配的小块区域。 需要首先给定一个模板图像A&#xff0c;和一个待检测图像B。 在待检测图像B上&#xff0c;从左往右&#xff0c;从上往下计算待检测图像B和模板图像A所重叠的匹配度&#xff0c;匹配度越高则两者相同的可…

基于WF的意见征集4(浅析)

接口项目&#xff1a;IClass&#xff08;项目名称&#xff09; HTHuiFuusing System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Workflow.Runtime;using System.Workflow.Activities;namespace IClass{ /// <summary> /…

那些VisualStudio隐藏的调试功能

VisualStudio是一个强大的调试工具&#xff0c;里面很多隐藏功能少有人问津&#xff0c;但是在特定场景可以节省你很多时间&#xff0c;本文主要介绍一些VisualStudio调试相关的隐藏功能&#xff0c;欢迎大家补充。 运行到指针(Run to cursor) 大多数人用Visual Studio在调试程…

php连接数据库代码_PHP代码连接各种数据库

php连接数据库代码1)用PHP连接MySQL (1) Connecting with MySQL in PHP) <?php$host "localhost";$uname "username";$pw "password";$db "newDB";try {$conn new PDO("mysql:host$host;dbname$db", $uname, $pw);…

【C++ grammar】对象和类(创建对象、对象拷贝、分离声明与实现)

目录1、用类创建对象1、面向对象的特征2、对象由什么构成3、如何定义对象4、创建对象并访问对象成员1. Constructors(构造函数)2. Constructing Objects (创建对象)3. Object Member Access Operator(对象访问运算符)2、对象拷贝以及分离声明与实现1、类是一种数据类型1.1. 定义…

十一、图像二值化

一、二值图像 其实就是把图像转换为只有黑白的两种颜色图像&#xff0c;即像素值非零即一 三角阈值二值化 对一个图像进行操作&#xff0c;获取图像的直方图&#xff0c;找到波峰和波谷进行连线设为线段A&#xff0c;每个点做有关线段A的垂线垂足在线段A上&#xff0c;最后将…

百度地图LV1.5实践项目开发工具类bmap.util.jsV1.2

/*** 百度地图使用工具类-v1.5* * author boonya* date 2013-7-7* address Chengdu,Sichuan,China* email boonyasina.com* company KWT.Shenzhen.Inc.com* notice 有些功能需要加入外部JS库才能使用&#xff0c;另外还需要申请地图JS key .* 申请地址&#xff1a;http…

isatty_带有示例的Python File isatty()方法

isatty文件isatty()方法 (File isatty() Method) isatty() method is an inbuilt method in Python, it is used to check whether a file stream is an interactive or not in Python i.e. a file stream is connected to a terminal device. If a file is connected to a ter…

地毯店 如何辨别地毯的好坏?

在实地选购地毯品牌时&#xff0c;许多地方需要引起注意&#xff0c;而且要显得专业&#xff0c;这样才能科学深入地辨别地毯的好坏。比如&#xff0c;辨明拉绞地毯和抽绞地毯两种工艺的打结方法几乎相同&#xff0c;只是变绞形式上有所区别。抽绞的方式较古老&#xff0c;一般…

十二、图像金字塔

一、原理 reduce高斯模糊降采样 expand扩大卷积 PyrDown&#xff1a;降采样 PyrUp&#xff1a;还原 二、高斯金字塔 import cv2 import numpy as np from matplotlib import pyplot as pltdef pyramid(image):level 3temp image.copy()pyramid_image []for i in range(le…

java uuid静态方法_Java UUID toString()方法与示例

java uuid静态方法UUID类toString()方法 (UUID Class toString() method) toString() method is available in java.util package. toString()方法在java.util包中可用。 toString() method is used for string denotation of this UUID. toString()方法用于此UUID的字符串表示…

LeetCode 110. 平衡二叉树思考分析

题目 给定一个二叉树&#xff0c;判断它是否是高度平衡的二叉树。 本题中&#xff0c;一棵高度平衡二叉树定义为&#xff1a; 一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。 示例 1: 给定二叉树 [3,9,20,null,null,15,7] 3 / 9 20 / 15 7 返回 true 。 示例 2…

Redhat配置XDMCP及相关linux命令

为了能够使用 Xwin32 或 Xmanager 登录到 Linux 主机所进行的配置。需要首先在linux上进行相关配置 1.“系统”菜单中选择“管理”下的“登录屏幕” 2.出现“登录窗口首选项”窗口。选择“远程”选项卡&#xff0c;将“样式”改为:“与本地相同” 3.选择“安全”选项卡&#xf…

充实的日子里忙忙碌碌

实习已经有一个多月了&#xff0c;话说这个月发工资就有我的份儿了&#xff0c;哇咔咔~~~感觉忙忙碌碌的生活其实很充实的。工作日每天都是7点10分左右起来&#xff0c;8点半到公司买早饭吃东西&#xff0c;9点上班开工。先罗列要干的东西&#xff0c;然后一项一项完成&#xf…

十三、图像梯度

一、两种算子 一阶导数—Sobel算子 水平梯度&#xff1a; 垂直梯度&#xff1a; 最终图像梯度&#xff1a; 二阶导数—Laplacian算子 在二阶导数的时候&#xff0c;最大变化处的值为零&#xff0c;即边缘是零值。 常见的拉普拉斯算子&#xff1a;、其所有元素之和为零。…

Java Formatter out()方法与示例

格式化程序类out()方法 (Formatter Class out() method) out() method is available in java.util package. out()方法在java.util包中可用。 out() method is used to get Appendable for the output. out()方法用于获取输出的Appendable。 out() method is a non-static meth…