【LeetCode】101.对称二叉树

文章目录

  • 问题描述
  • 法I:递归实现
  • 法II:递归(官方题解)
  • 法III:迭代实现(利用中序遍历:左中右/右中左)
  • 法IV:迭代(官方题解)

问题描述

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

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

【LeetCode】101.对称二叉树_第1张图片

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

【LeetCode】101.对称二叉树_第2张图片

进阶:

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/symmetric-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

法I:递归实现

代码:

//对称二叉树——递归实现
class Solution {
public:
	bool isSymmetric(TreeNode* root) {
		if (root != nullptr) {
			return helper(root->left, root->right);
		}
		else {
			return true;
		}
	}

	bool helper(TreeNode* leftTree, TreeNode* rightTree) {
		if (leftTree == nullptr && rightTree == nullptr) {
			return true;
		}
		else if (leftTree != nullptr && rightTree != nullptr) {
			if (leftTree->val != rightTree->val) {
				return false;
			}
			return helper(leftTree->left, rightTree->right) && helper(leftTree->right, rightTree->left);
		}
		else {//两个树,只有一个是Null
			return false;
		}
	}
};

执行结果:
【LeetCode】101.对称二叉树_第3张图片
大概写一下代码思路:

递归函数helper实现的是两棵树是否呈镜像。

边界条件是这两棵树都是空,那么返回true

对于一些特殊情况我们可以单独来考虑以提高效率:1.若只有一个树是空,那么返回false; 2.若两个树都不为空但是根结点值不相等,那么返回false

剩余的是递归的情况:我们考虑这两棵树的子树的镜像情况:1.leftTree的左子与rightTree的右子是否呈镜像; 2.leftTree的右子与rightTree的左子是否呈镜像。之后返回其相与的布尔值即可。

法II:递归(官方题解)

其实和我的思路是一样的,只不过这个官方代码是更加简洁的。

class Solution {
public:
    bool check(TreeNode *p, TreeNode *q) {
        if (!p && !q) return true;
        if (!p || !q) return false;
        return p->val == q->val && check(p->left, q->right) && check(p->right, q->left);
    }

    bool isSymmetric(TreeNode* root) {
        return check(root, root);
    }
};

法III:迭代实现(利用中序遍历:左中右/右中左)

//迭代实现——通过中序遍历
class Solution {
public:
	bool isSymmetric(TreeNode* root) {
		if (root == nullptr) {
			return true;
		}
		TreeNode* currentLeft = root->left;
		TreeNode* currentRight = root->right;
		stack<TreeNode*> stLeft;
		stack<TreeNode*> stRight;
		while ((currentLeft != nullptr || !stLeft.empty()) && (currentRight != nullptr || !stRight.empty())) {
			while (currentLeft != nullptr && currentRight != nullptr) {
				stLeft.push(currentLeft);
				currentLeft = currentLeft->left;
				stRight.push(currentRight);
				currentRight = currentRight->right;
			}
			if (currentLeft == nullptr && currentRight == nullptr) {
				currentLeft = stLeft.top();
				stLeft.pop();
				currentRight = stRight.top();
				stRight.pop();
				if (currentLeft->val != currentRight->val) {
					return false;
				}
				currentLeft = currentLeft->right;
				currentRight = currentRight->left;
			}
			else {
				return false;
			}
		}
		if (!(currentLeft != nullptr || !stLeft.empty()) && !(currentRight != nullptr || !stRight.empty())) {
			return true;
		}
		else {
			return false;
		}
	}
};

【LeetCode】101.对称二叉树_第4张图片
分析:若左子树通过左中右完成中序遍历,右子树通过右中左完成中序遍历,则两者在输出(出栈)时对应的值应该是一样的。否则说明不是镜像。

法IV:迭代(官方题解)

「方法一」中我们用递归的方法实现了对称性的判断,那么如何用迭代的方法实现呢?首先我们引入一个队列,这是把递归程序改写成迭代程序的常用方法。初始化时我们把根节点入队两次。每次提取两个结点并比较它们的值(队列中每两个连续的结点应该是相等的,而且它们的子树互为镜像),然后将两个结点的左右子结点按相反的顺序插入队列中。当队列为空时,或者我们检测到树不对称(即从队列中取出两个不相等的连续结点)时,该算法结束。

class Solution {
public:
    bool check(TreeNode *u, TreeNode *v) {
        queue <TreeNode*> q;
        q.push(u); q.push(v);
        while (!q.empty()) {
            u = q.front(); q.pop();
            v = q.front(); q.pop();
            if (!u && !v) continue;
            if ((!u || !v) || (u->val != v->val)) return false;

            q.push(u->left); 
            q.push(v->right);

            q.push(u->right); 
            q.push(v->left);
        }
        return true;
    }

    bool isSymmetric(TreeNode* root) {
        return check(root, root);
    }
};

注意队列的先进先出

你可能感兴趣的:(力扣打卡,leetcode,算法)