数据结构和算法十四

剑指 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仍旧会更新博客!之前也说过,这是我每天给自己的要求!除非特别忙,会在第二天的凌晨会把前一天的博客补起来!放假也不能忘记学习呦!玩归玩,学归学!多的也没什么说的了,继续努力!
       最后,愿我们都能在各行各业中能够取得不同的成就!能够用自身的所学知识为国家贡献出自己的一份力量!一起加油!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值