28. 对称的二叉树¹
请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。
例如,二叉树 [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
示例 1:
输入:root = [1,2,2,3,4,4,3]
输出:true
示例 2:
输入:root = [1,2,2,null,3,null,3]
输出:false
限制:
0 <= 节点个数 <= 1000
注意:本题与主站 101 题相同:leetcode-cn.com/problems/sy…
1.分治*
- 思路:
- 对称特征
- 根节点:为空时对称
- 第二级节点:必须相同
- 第 >= 三级节点:left.left = right.right && left.right = right.left
- 分治:每个节点都对称,则总体对称
- 函数:boolean f (right, left)
- 结束条件:root = null
- 分解:s.val == t.val && isSymmetirc(s.left, t.right) && isSymmetirc(s.right, t.left)
- 合并:直接放回分解结果即可
// Time:O(n), Space:O(n)
class Solution {
public boolean isSymmetric(TreeNode root) {
if (root == null) return true;
return isSymmetric(root.left, root.right);
}
private boolean isSymmetric(TreeNode s, TreeNode t) {
if (s != null && t != null)
return s.val == t.val && isSymmetric(s.left, t.right) && isSymmetric(s.right, t.left);
else
return s == null && t == null;
}
}
2.DFS(栈)
迭代借助栈实现更好理解一点
// Time:O(n), Space:O(n)
public boolean isSymmetric(TreeNode root) {
if (root == null) return true;
Stack<TreeNode> stack = new Stack<>();
stack.push(root.left);
stack.push(root.right);
while (!stack.isEmpty()) {
TreeNode r = stack.pop(), l = stack.pop();
// 1.两个节点都为空,则当前节点对称
if (r == null && l == null) continue;
// 2.一个节点为空,部队称
if (r == null || l == null) return false;
// 3.两个节点都非空,判断这两个节点是否相同
// 3.1 不同则不对称
if (r.val != l.val) return false;
// 3.2 相同,再按序入栈(这里的顺序必要一边left,一边right)
stack.push(r.left);
stack.push(l.right);
stack.push(r.right);
stack.push(l.left);
}
return true;
}
100. 相同的树¹
给定两个二叉树,编写一个函数来检验它们是否相同。
如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
示例 1:
输入: 1 1
/ \ / \
2 3 2 3
[1,2,3], [1,2,3]
输出: true
示例 2:
输入: 1 1
/ \
2 2
[1,2], [1,null,2]
输出: false
示例 3:
输入: 1 1
/ \ / \
2 1 1 2
[1,2,1], [1,1,2]
输出: false
1.分治*
public boolean isSameTree(TreeNode p, TreeNode q) {
if (p == null && q == null) return true;
if (p == null || q == null) return false;
if (p.val != q.val) return false;
return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
}
2.DFS(栈)
同下面BFS,Queue换成stack即可
3.BFS
// 双队列,没必要
// Time:O(n), Space:O(n)
public boolean isSameTree(TreeNode p, TreeNode q) {
// 注意:这里的判断条件
if (p == null && q == null) return true;
if (p == null || q == null) return false;
Queue<TreeNode> queueP = new LinkedList<>();
Queue<TreeNode> queueQ = new LinkedList<>();
queueP.offer(p);
queueQ.offer(q);
while (!queueP.isEmpty() || !queueQ.isEmpty()) {
TreeNode p1 = queueP.poll();
TreeNode q1 = queueQ.poll();
// 1.两个都空
if (p1 == null && q1 == null) continue;
// 2.一个空
if (p1 == null || q1 == null) return false;
// 3.两个都不空
if (p1.val != q1.val ) return false;
// 注:这里的入队顺序:同一队中先左后右
queueP.offer(p1.left);
queueP.offer(p1.right);
queueQ.offer(q1.left);
queueQ.offer(q1.right);
}
return true;
}
// Time:O(n), Space:O(n)
public boolean isSameTree(TreeNode p, TreeNode q) {
if (p == null && q == null) return true;
if (p == null || q == null) return false;
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(p);
queue.offer(q);
while (!queue.isEmpty()) {
// 一次出两个节点就行了
TreeNode p1 = queue.poll();
TreeNode q1 = queue.poll();
if (p1 == null && q1 == null) continue;
if (p1 == null || q1 == null) return false;
if (p1.val != q1.val ) return false;
// 注:这里的入队顺序:先左后右
queue.offer(p1.left);
queue.offer(q1.left);
queue.offer(p1.right);
queue.offer(q1.right);
}
return true;
}