|
| 1 | +## 题目地址(101. 对称二叉树) |
| 2 | + |
| 3 | +https://leetcode-cn.com/problems/symmetric-tree/ |
| 4 | + |
| 5 | +## 题目描述 |
| 6 | + |
| 7 | +``` |
| 8 | +给定一个二叉树,检查它是否是镜像对称的。 |
| 9 | +
|
| 10 | + |
| 11 | +
|
| 12 | +例如,二叉树 [1,2,2,3,4,4,3] 是对称的。 |
| 13 | +
|
| 14 | + 1 |
| 15 | + / \ |
| 16 | + 2 2 |
| 17 | + / \ / \ |
| 18 | +3 4 4 3 |
| 19 | + |
| 20 | +
|
| 21 | +但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的: |
| 22 | +
|
| 23 | + 1 |
| 24 | + / \ |
| 25 | + 2 2 |
| 26 | + \ \ |
| 27 | + 3 3 |
| 28 | + |
| 29 | +
|
| 30 | +进阶: |
| 31 | +
|
| 32 | +你可以运用递归和迭代两种方法解决这个问题吗? |
| 33 | +
|
| 34 | +
|
| 35 | +``` |
| 36 | + |
| 37 | +## 思路 |
| 38 | + |
| 39 | +看到这题的时候,我的第一直觉是 DFS。然后我就想:`如果左子树是镜像,并且右子树也是镜像,是不是就说明整体是镜像?`。经过几秒的思考, 这显然是不对的,不符合题意。 |
| 40 | + |
| 41 | + |
| 42 | + |
| 43 | +很明显其中左子树中的节点会和右子树中的节点进行比较,我把比较的元素进行了颜色区分,方便大家看。 |
| 44 | + |
| 45 | +这里我的想法是:`遍历每一个节点的时候,我都可以通过某种方法知道它对应的对称节点是谁。这样的话我直接比较两者是否一致就行了。` |
| 46 | + |
| 47 | +最初我的想法是两次遍历,第一次遍历的同时将遍历结果存储到哈希表中,然后第二次遍历去哈希表取。 |
| 48 | + |
| 49 | +这种方法可行,但是无需要 N 的空间(N 为节点总数)。我想到如果两者可以同时进行遍历,是不是就省去了哈希表的开销。 |
| 50 | + |
| 51 | +如果不明白的话,我举个简单例子: |
| 52 | + |
| 53 | +``` |
| 54 | +给定一个数组,检查它是否是镜像对称的。例如,数组 [1,2,2,3,2,2,1] 是对称的。 |
| 55 | +``` |
| 56 | + |
| 57 | +如果用哈希表的话大概是: |
| 58 | + |
| 59 | +```py |
| 60 | +seen = dict() |
| 61 | +for i, num in enumerate(nums): |
| 62 | + seen[i] = num |
| 63 | +for i, num in enumerate(nums): |
| 64 | + if seen[len(nums) - 1 - i] != num: |
| 65 | + return False |
| 66 | +return True |
| 67 | +``` |
| 68 | + |
| 69 | +而同时遍历的话大概是这样的: |
| 70 | + |
| 71 | +```py |
| 72 | +l = 0 |
| 73 | +r = len(nums) - 1 |
| 74 | + |
| 75 | +while l < r: |
| 76 | + if nums[l] != nums[r]: return False |
| 77 | +return True |
| 78 | + |
| 79 | +``` |
| 80 | + |
| 81 | +## 代码 |
| 82 | + |
| 83 | +```py |
| 84 | + |
| 85 | +class Solution: |
| 86 | + def isSymmetric(self, root: TreeNode) -> bool: |
| 87 | + def dfs(root1, root2): |
| 88 | + if root1 == root2: return True |
| 89 | + if not root1 or not root2: return False |
| 90 | + if root1.val != root2.val: return False |
| 91 | + return dfs(root1.left, root2.right) and dfs(root1.right, root2.left) |
| 92 | + if not root: return True |
| 93 | + return dfs(root.left, root.right) |
| 94 | +``` |
| 95 | + |
| 96 | +**_复杂度分析_** |
| 97 | + |
| 98 | +- 时间复杂度:$O(N)$,其中 N 为节点数。 |
| 99 | +- 空间复杂度:递归的深度最高为节点数,因此空间复杂度是 $O(N)$,其中 N 为节点数。 |
| 100 | + |
| 101 | +更多题解可以访问我的 LeetCode 题解仓库:https://github.com/azl397985856/leetcode 。 目前已经 30K star 啦。 |
| 102 | + |
| 103 | +大家也可以关注我的公众号《脑洞前端》获取更多更新鲜的 LeetCode 题解 |
| 104 | + |
| 105 | + |
0 commit comments