zoukankan      html  css  js  c++  java
  • 对称的二叉树(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 };
  • 相关阅读:
    java基础知识(一)- 数据类型
    Java基础知识-去重
    java基础知识-冒泡排序
    Java排序方法sort的使用详解
    Java面试题-字符串操作
    Map.Entry遍历Map
    Java中String的用法
    Java循环控制语句-switch
    API文档打开显示'已取消到该网页的导航'的解决方法
    CentOS6.5 安装snort
  • 原文地址:https://www.cnblogs.com/kongzimengzixiaozhuzi/p/13260006.html
Copyright © 2011-2022 走看看