剑指 Offer 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
/*解题思路:
对称二叉树定义: 对于树中 任意两个对称节点L和R,一定有:
L.val=R.val:即此两对称节点值相等。
L.left.val = R.right.val:即L的左子节点和R的右子节点对称;
L.right.val = R.left.val:即L的右子节点和R的左子节点对称。
根据以上规律,考虑从顶至底递归,判断每对节点是否对称,从而判断树是否为对称二叉树。
*/
/*
算法流程:
isSymmetric(root) :
特例处理: 若根节点 root 为空,则直接返回true 。
返回值: 即 recur(root.left, root.right) ;
recur(L, R) :
终止条件:
当L和R同时越过叶节点:此树从顶至底的节点都对称,因此返回true;
当L或R中只有一个越过叶节点:此树不对称,因此返回false;
当节点L值≠节点R值:此树不对称,因此返回false;
递推工作:
判断两节点L.left和R.right是否对称,即recur(L.left, R.right) ;
判断两节点L.right和R.left是否对称,即 recur(L.right, R.left) ;
返回值:两对节点都对称时,才是对称树,因此用与逻辑符 && 连接。
复杂度分析:
时间复杂度O(N):其中N为二叉树的节点数量,每次执行recur()可以判断一对节点是否对称,因此最多调用N/2次recur()方法。
空间复杂度O(N):最差情况下(见下图),二叉树退化为链表,系统使用O(N) 大小的栈空间。
*/
class Method{
public boolean isSymmetric(TreeNode root) {
return root == null ? true : recur(root.left, root.right);
}
boolean recur(TreeNode L, TreeNode R) {
if(L == null && R == null) return true;
if(L == null || R == null || L.val != R.val) return false;
return recur(L.left, R.right) && recur(L.right, R.left);
}
}
剑指 Offer 32 - I. 从上到下打印二叉树 I
题目:从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。
例如:
给定二叉树: [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回:[3,9,20,15,7]
提示:
节点总数 <= 1000
/*解题思路:
题目要求的二叉树的 从上至下 打印(即按层打印),又称为二叉树的广度优先搜索(BFS)。
BFS 通常借助队列的先入先出特性来实现。
算法流程:
1、特例处理:当树的根节点为空,则直接返回空列表[];
2、初始化:打印结果列表res=[],包含根节点的队列queue=[root];
3、BFS循环:当队列queue为空时跳出;
` (1)出队:队首元素出队,记为node;
` (2)打印:将node.val添加至列表tmp尾部;
(3)添加子节点:若node的左(右)子节点不为空,则将左(右)子节点加入队列queue;
4、返回值:返回打印结果列表res即可。
复杂度分析:
时间复杂度O(N):N为二叉树的节点数量,即BFS需循环N次。
空间复杂度O(N):最差情况下,即当树为平衡二叉树时,最多有N/2个树节点同时在queue中,使用O(N)大小的额外空间。
*/
class Method{
public int[] levelOrder(TreeNode root) {
if(root == null) return new int[0];
Queue<TreeNode> queue = new LinkedList<>(){{ add(root); }};
ArrayList<Integer> ans = new ArrayList<>();
while(!queue.isEmpty()) {
TreeNode node = queue.poll();
ans.add(node.val);
if(node.left != null) queue.add(node.left);
if(node.right != null) queue.add(node.right);
}
int[] res = new int[ans.size()];
for(int i = 0; i < ans.size(); i++)
res[i] = ans.get(i);
return res;
}
}
总结:
不知不觉今天就是5.1了,时间过得真快!昨天还是月底,今天就是月初了!在此先预祝各位小伙伴们5.1快乐!小长假可以缓解一下压力,但是外出的同时还是要注意疫情的防控哦!我的5.1仍旧会更新博客!之前也说过,这是我每天给自己的要求!除非特别忙,会在第二天的凌晨会把前一天的博客补起来!放假也不能忘记学习呦!玩归玩,学归学!多的也没什么说的了,继续努力!
最后,愿我们都能在各行各业中能够取得不同的成就!能够用自身的所学知识为国家贡献出自己的一份力量!一起加油!