LeetCode | Symmetric Tree(镜像树)

Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center).

For example, this binary tree is symmetric:

    1
   / \
  2   2
 / \ / \
3  4 4  3

But the following is not:

    1
   / \
  2   2
   \   \
   3    3

Note:
Bonus points if you could solve it both recursively and iteratively.

题目解析:

判断一棵树是否为左右镜像对称的树。如果能用递归和非递归两种实现更好。


方案一:递归方法

设一个函数,递归的时候,传入p的左子树和传入q的右子树递归,再传入p的右子树和q的左子树递归。然后判断返回值是否都为真。

一开始不一定能想到这种方法,多画图判断。

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

        if(p->val != q->val)
            return false;

        return CompareTree(p->left,q->right) && CompareTree(p->right,q->left);
    }
};

方案二:非递归方法

非递归的实现就要借助栈或者队列。栈的话,本身就是一种递归的方法。这里看看用队列能否实现。

一开始想的设置一个队列,入队列的时候,按照p->left,q->right,p->right,q->left的顺序。然后取出队列,要一次取出两个。当然碰到叶节点的时候的空指针要额外处理一下。同时防止左右子树不等长的情况。有点繁琐,不过还是能实现的。

我们也可以设置两个队列,根的左子树一个,根的右子树一个。队列中放入指向结点的指针。一边出队列,一边将该结点的左右孩子入队列。当然也要遵循左右交替的入队列。

/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    bool isSymmetric(TreeNode *root) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        if(root==NULL)return true;
        queue<TreeNode*> lt,rt;
    	if(root->left) lt.push(root->left);
		if(root->right) rt.push(root->right);
		TreeNode* l;
		TreeNode* r;
		while(!lt.empty() && !rt.empty())
		{
			l = lt.front();lt.pop();
			r = rt.front();rt.pop();
			if(l == NULL && r == NULL) continue;
			if(l == NULL || r == NULL) return false;
			if(l->val != r->val) return false;
			lt.push(l->left);
			lt.push(l->right);
            rt.push(r->right);
			rt.push(r->left);
		}
		if(lt.empty() && rt.empty())
			return true;
		else
			return false;
    }
};

错误的方案:

由于是一个对称的树,中序遍历的话,得到的序列关于中心对称。

但如果是{1,2,3,3,#,2,#} 例子,得到的中序遍历为32123。但这棵树不是对称树。不能想当然的这样认为。




点赞