Loading

剑指 Offer 28. 对称的二叉树

思路

一开始想用左根右遍历的序列和右根左遍历的序列进行比较,如果相等则镜像对称。后来发现这种方式不对,比如样例[1, 2, 2, null, 2]就不是镜像对称的,但这种方法会返回true。

方法一:递归

 

 

 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10 class Solution {
11 public:
12     bool isSymmetric(TreeNode* root) {
13         if(root == NULL)    
14             return true;
15         return check(root->left, root->right);
16     }
17 
18     bool check(TreeNode* L, TreeNode* R) {
19         if(L == NULL && R == NULL)
20             return true;
21         
22         if(L != NULL && R != NULL && L->val == R->val)
23             return check(L->left, R->right) && check(L->right, R->left); 
24         
25         return false;
26     }
27     
28 };

 

复杂度分析:

时间复杂度 O(N) : 其中 N 为二叉树的节点数量,每次执行 check() 可以判断一对节点是否对称,因此最多调用 N/2 次 check() 方法。
空间复杂度 O(N) : 最差情况下,二叉树退化为链表,系统使用 O(N)大小的栈空间。

 

方法二:非递归(迭代)

方法一中我们用递归的方法实现了对称性的判断,那么如何用迭代的方法实现呢?

首先我们引入一个队列,这是把递归程序改写成迭代程序的常用方法。

初始化时我们把根节点入队两次。每次提取两个结点并比较它们的值(队列中每两个连续的结点应该是相等的,而且它们的子树互为镜像),然后将两个结点的左右子结点按相反的顺序插入队列中。

当队列为空时,或者我们检测到树不对称(即从队列中取出两个不相等的连续结点)时,该算法结束。

 

 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10 class Solution {
11 public:
12     bool isSymmetric(TreeNode* root) {
13         if(root == NULL)
14             return true;
15         return check(root->left, root->right);
16     }
17 
18     bool check(TreeNode *u, TreeNode *v) {
19         queue <TreeNode*> q;
20         q.push(u); q.push(v);
21         while (!q.empty()) {
22             u = q.front(); q.pop();
23             v = q.front(); q.pop();
24             if (!u && !v) continue;
25             if ((!u || !v) || (u->val != v->val)) return false;
26 
27             q.push(u->left); 
28             q.push(v->right);
29 
30             q.push(u->right); 
31             q.push(v->left);
32         }
33         return true;
34     }
35 };

复杂度分析:

时间复杂度:O(n),同「方法一」。
空间复杂度:这里需要用一个队列来维护节点,每个节点最多进队一次,出队一次,队列中最多不会超过 n 个点,故渐进空间复杂度为 O(n)。

 

参考

力扣官方题解-对称二叉树

面试题28. 对称的二叉树(递归,清晰图解)

posted @ 2020-10-27 11:18  拾月凄辰  阅读(76)  评论(0编辑  收藏  举报