day15 102.二叉树的层序遍历 226. 翻转二叉树 101. 对称二叉树

文档讲解:代码随想录(代码随想录

完成状态:  true

 102. 二叉树的层序遍历

思路:
         层序遍历很容易想到用队列来解决,队列是先进先出的,可以保存一层又一层的二叉树节点。直接输出层序遍历的顺序是比较简单的,比较难的是怎么想到对每一层进行单独的保存操作。

        这里可以每次遍历之前保存队列当前的长度,此时其长度就是当前层的节点个数,有了这个长度ze记录当前层的元素个数后,既可以对这一层节点进行输出,同时遍历这一层节点后,就可以讲对应的下一层节点全部放入队列中,此时的节点个数也就是下次循环size记录的节点个数。

class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> result = new ArrayList<List<Integer>>();
        if(root == null){
            return result;
        }
        Queue<TreeNode> queue = new LinkedList<TreeNode>();
        queue.offer(root);
        while(!queue.isEmpty()){
            List<Integer> itemList = new ArrayList<Integer>();
            int size = queue.size();  // 保存每一层的节点个数
            while(size > 0){
                TreeNode node = queue.poll();
                itemList.add(node.val);
                if(node.left != null){
                    queue.offer(node.left);
                }
                if(node.right != null){
                    queue.offer(node.right);
                }
                size--;
            } 
            result.add(itemList);
        }
        return result;
    }
}

226. 翻转二叉树

        最开始只想到了后序遍历,但是进一步一想,前序遍历也是可以的。只不过前序遍历是从顶部到底部去反转二叉树,而后序遍历则是从底部到顶部去反转。       

后序遍历:

class Solution {
    public TreeNode invertTree(TreeNode root) {
        if(root == null){
            return null;
        }
        invertTree(root.left); // 左
        invertTree(root.right); // 右
        // 根 反转二叉树
        TreeNode temp = new TreeNode();
        temp = root.left;
        root.left = root.right;
        root.right = temp;
        return root;
    }
}

中序遍历: 

        但是中序遍历是不可以的,因为中序遍历在第一次正常交换了左右节点后,回退到上一层,再一次交换左右节点后,由于是左根右,此时也正需递归遍历右子树了,此时由于已经交换过了,如果继续递归root.right,此时的右子树实际上是已经反转过的左子树。

        所以实际上处理逻辑应该是左根左,最后的左实际是未交换前的右子数。

101. 对称二叉树

        一开始拿到这个题思路是混乱的,我认为这道题还是有些难度的,因为之前并未遇到同时遍历两个二叉树的情况。

        考虑这样的一个题目,有两个独立的二叉树,现在让你判断这两个二叉树是否完全一致。这就是要去同时遍历两个二叉树的情况。首先想清楚这是否是个递归问题?是的话用什么遍历顺序?        

  • 递归问题。假如两个独立的二叉树如下,首先判断两个二叉树整体是不是完全一致,此时根节点是左图的2和右图的2,也就是需要判断两个二叉树的左子树和右子树是否完全一致。这个时候就发现,两个二叉树的左子树(右子树)又是一个二叉树结构,此时变为判断他们以3为根节点的两个二叉树是否完全一致,也就是需要判断以3为根节点的左图的二叉树和右图的二叉树的左右子树是否完全一致。接下来...可以看到这就是一个标准的递归结构。

                      每一次都是去判断两个不同二叉树左右子树是否完全一致的过程。

  • 后序遍历。本质是后序遍历的变体。需要我们收集左右孩子的信息后,并向上一层(根节点)返回的时候,这类题目是需要后序遍历的。

        对称二叉树也就是左子树和右子树是可以互相反转的,反转任意一个二叉树,两个二叉树就是完全一致的。有了上述的引入,这道题就迎刃而解了。        

        第一次写完代码运行报错,如下所示。问题出在每次判断都去判断当前节点的左节点和右节点,但是若当前节点已经为空,则会产生空指针异常。还是对问题没有思考透彻。

class Solution {
    public boolean isSymmetric(TreeNode root) {
        if(root == null){
            return true;
        }
        return compare(root.left, root.right);
    }

    public boolean compare(TreeNode leftTreeRoot, TreeNode rightTreeRoot){
        if(leftTreeRoot != null && rightTreeRoot == null){
            return false;
        }
        if(leftTreeRoot == null && rightTreeRoot != null){
            return false;
        }
        if(leftTreeRoot == null && rightTreeRoot == null){
            return true;
        }
        if(leftTreeRoot.val != rightTreeRoot.val){  // 左右都不为空,但是数值不相等
            return false;
        }
        // 后序遍历
        boolean outSide = compare(leftTreeRoot.left, rightTreeRoot.right);
        boolean inSide = compare(leftTreeRoot.right, rightTreeRoot.left);
        boolean result = outSide && inSide;
        return result;
    }
}

  • 11
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值