【LeetCode】101.对称二叉树

【LeetCode】101.对称二叉树

/*	
*  转载请说明出处与作者
*  作者:多巴胺dopamine
*/

一 问题描述

1 题目

给你一个二叉树的根节点 root , 检查它是否轴对称。

示例 1:
symtree1.jpg

输入:root = [1,2,2,3,4,4,3]
输出:true

示例 2:
symtree2.jpg

输入:root = [1,2,2,null,3,null,3]
输出:false

提示:
树中节点数目在范围 [1, 1000] 内
-100 <= Node.val <= 100
进阶:你可以运用递归和迭代两种方法解决这个问题吗?

二 解题

1 解题思路

1.1 一个错误打开思路

使用二叉树的中序遍历,结果判断得到的数组是否是中间对称的。博主一开始就是按照这个思路来的,最后发现总会有几个示例不能通过。
回忆一个知识点:如何确定一个二叉树?
需要一个中序遍历加上一个其他遍历的序列才可以唯一确定一个二叉树。按照中序遍历后再判断是否是中间对称的错误点就在这里。

1.2 正确的思路

不论是递归实现还是迭代实现,其实都可以看做运用了一个双指针。

1.2.1 递归思路

以示例1为例:
image.png
判断该二叉树是否是一个对称二叉树,只需要判断以 第二层为根节点 的两个二叉树(左边称树1,右边称树2)相等,即满足:
(1) 树1,树2的两个节点的 val 值相等;
(2) 树1的左子树 == 树2的右子树;(至于怎么判断这两个子树相等,不就运用递归了嘛)
(3) 树1的右子数 == 树2的左子树;

1.2.2 迭代思路

同样使用双指针,但是使用层次遍历(运用到队列),每次出队列两个。
以示例1为例:
image.png

每次出队列两个(红,蓝,绿的顺序),只要每次判断都相等,那么这个二叉树就是轴对称的。
那么问题来了,入队列的顺序呢?
很简单,因为使用了双指针,在判断完红色指针的节点相等时,就可以按照 q -> left、p -> right 、q -> right、p->left 的顺序入队了。

2 上代码%)RK8(`~{5PA(@43ARLWE_I.png(很详细的注释)

复制下去看,代码结构更清晰一些。不同网站对缩进、空格的解析不同有时会显得代码很乱。

2.1 递归解法

/**
* Definition for a binary tree node.
* struct TreeNode {
*     int val;
*     struct TreeNode *left;
*     struct TreeNode *right;
* };
*/

bool check();
/*
* 初始化函数
*/
bool isSymmetric(struct TreeNode* root){
	bool is=check(root->left,root->right);
	return is;
}
/*
*	判断两个二叉树是否完全相同的函数
*	参数说明:
*	left,一个指针;right,右一个指针。(指向需要判断的两个二叉树的根节点位置)
*/
bool check(struct TreeNode* left,struct TreeNode* right){
	// 如果两个节点都是  NULL,相同
	if(!left && !right) return true;
	// 有一个是 NULL 一个不是 NULL (都是 NULL 的话在上面就 return 了),不相同
	if(!left || !right) return false;
	// 都不是 NULL。
	// 开始判断 val 值是否相等;树1的左子树是否等于树2的右子树;树1的右子树是否等于树2的左子树
	//	有一个false,结果就会时false了
	return left->val==right->val && check(left->left,right->right) && check(left->right,right->left);
}

2.2 迭代解法

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */


bool isSymmetric(struct TreeNode* root){
	// 开辟一个足够大队列空间,图省事不想去写循环队列。
  struct TreeNode** Queue=(struct TreeNode **)malloc(sizeof(struct TreeNode*)*2001);
  //	front 队首,rear 队尾
	int front=0; int rear=0;
  //	返回值
	bool is=true;
	//	先将根节点的左右子树入队(题目有说明至少有一个节点,就不用考虑 root 是 NULL 的情况了)
  Queue[rear++]=root->left;
  Queue[rear++]=root->right;
  //	循环条件,队列不为空
	while(front!=rear){
		//	从对首拿出两个
    struct TreeNode* p=Queue[front++];
    struct TreeNode* q=Queue[front++];
    //	都是 NULL 相同了,继续下一次循环吧
		if (!p && !q){
      continue;
    }
		//	一个为 NULL,一个不为 NULL;两个节点的 val 值不相等都是不对称的情况。直接 false 且结束循环
		if((!p && q) || (p && !q) || (p->val!=q->val) ){
      is=false;
      break;
    }
	//走到这一步,两个节点都不是	NULL 且 val 值相等。那就把子树入队吧(注意顺序)
    Queue[rear++]=p->left;
    Queue[rear++]=q->right;
    Queue[rear++]=p->right;
    Queue[rear++]=q->left;
  }
  return is;
}

三 总结

  注意要想唯一确认一个二叉树需要中序遍历序列 + 一个其他遍历序列才可以。
posted @ 2022-08-18 23:01  多巴胺dopamine  阅读(19)  评论(0编辑  收藏  举报