对称的二叉树(Python and C++解法)

题目:

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

例如,二叉树 [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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/symmetric-tree

思路:

  如果一个树的左子树与右子树镜像对称,那么这个树是对称的。

  两个树互为镜像需要满足:它们的两个根结点具有相同的值;每个树的右子树都与另一个树的左子树镜像对称。

  可以递归解决,通过同步移动两个指针的方法来遍历这棵树,p指针和q指针一开始都指向这棵树的根,随后p右移时,q左移,p左移时,q右移。每次检查当前p和q节点的值是否相等,如果相等再判断左右子树是否对称。

  也可以迭代解决,首先我们引入一个队列,这是把递归改写成迭代的常用方法。初始化时需要把根节点入队 两次。每次提取两个结点并比较它们的值(如果树对称,队列中每两个连续的结点应该是相等的,而且它们的子树互为镜像),然后将两个结点的左右子结点按对称的顺序插入队列中。当队列为空时,或者检测到树不对称(即从队列中取出两个不相等的连续结点)时,该算法结束。

Python递归解法:

 1 class TreeNode:
 2     def __init__(self, x):
 3         self.val = x
 4         self.left = None
 5         self.right = None
 6 
 7 class Solution:
 8     def isSymmetric(self, root: TreeNode) -> bool:
 9         return self.check(root, root)
10 
11     def check(self, nodeP, nodeQ):
12         if not nodeP and not nodeQ:  # 如果同时遇到空节点
13             return True
14         if not nodeP or not nodeQ:  # 因为上面一次判断,已经排除!nodeP and !nodeQ的情况
15             return False
16         if nodeP.val == nodeQ.val:
17             return self.check(nodeP.left, nodeQ.right) and self.check(nodeP.right, nodeQ.left)
18         return False

Python迭代解法:

 1 class TreeNode:
 2     def __init__(self, x):
 3         self.val = x
 4         self.left = None
 5         self.right = None
 6 
 7 class Solution:
 8     def isSymmetric(self, root: TreeNode) -> bool:
 9         return self.check(root, root)
10 
11     def check(self, nodeP, nodeQ):
12         queue = []
13         queue.append(nodeP)
14         queue.append(nodeQ)
15 
16         while len(queue):
17             nodeP = queue.pop(0)  # python的pop默认返回列表最后一个元素
18             nodeQ = queue.pop(0)
19             if not nodeP and not nodeQ:
20                 continue
21             if (not nodeP or not nodeQ) or nodeP.val != nodeQ.val:
22                 return False
23             queue.append(nodeP.left)
24             queue.append(nodeQ.right)
25 
26             queue.append(nodeP.right)
27             queue.append(nodeQ.left)
28         return True

C++递归解法:

 1 struct TreeNode {
 2     int val;
 3     TreeNode *left;
 4     TreeNode *right;
 5     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 6 };
 7 
 8 class Solution {
 9 public:
10     bool check(TreeNode *nodeP, TreeNode *nodeQ) {
11         if (!nodeP && !nodeQ)
12             return true;
13         if (!nodeP || !nodeQ)
14             return false;
15         if (nodeP->val == nodeQ->val)
16             return check(nodeP->left, nodeQ->right) && check(nodeP->right, nodeQ->left);
17         return false;  // 前面都是if,此处必须有返回
18     }
19 
20     bool isSymmetric(TreeNode* root) {
21         return check(root, root);
22     }
23 };

C++迭代解法:

 1 struct TreeNode {
 2     int val;
 3     TreeNode *left;
 4     TreeNode *right;
 5     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 6 };
 7 
 8 class Solution {
 9 public:
10     bool check(TreeNode *nodeP, TreeNode *nodeQ) {
11         queue<TreeNode*> que;
12         que.push(nodeP);  que.push(nodeQ);  // 同时入队两个父节点
13         while (!que.empty()) {
14             nodeP = que.front(); que.pop();  // 取出第一个父节点,C++的pop()只删除不返回
15             nodeQ = que.front(); que.pop();  // 取出第二个父节点
16             if (!nodeP && !nodeQ)
17                 continue;  // 当前节点均为空,继续判断其他节点
18             // 在上面if的基础上,如果节点不同时为空,或节点不相等,则树不对称
19             if ((!nodeP || !nodeQ) || (nodeP->val != nodeQ->val))
20                 return false;
21             que.push(nodeP->left);    que.push(nodeQ->right);
22             que.push(nodeP->right);   que.push(nodeQ->left);
23         }
24         return true;
25     }
26 
27     bool isSymmetric(TreeNode* root) {
28         return check(root, root);  // 参数变成两个
29     }
30 };
posted @ 2020-07-07 12:04  孔子?孟子?小柱子!  阅读(220)  评论(0编辑  收藏  举报