代码随想录算法训练营Day15|102.二叉树的层序遍历 226.翻转二叉树 101.对称二叉树

102.二叉树的层序遍历

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> res = new ArrayList<List<Integer>>();//List是接口 无法实例化 因此只能实例化ArrayList
        if(root == null) return res;
        LinkedList<TreeNode> queue = new LinkedList<TreeNode>();//用来存放待弹出的节点
        queue.offer(root);
        while(!queue.isEmpty()){
            ArrayList<Integer> resLine = new ArrayList<Integer>();//存放每一行的结果
            int len = queue.size();
            for(int i=0;i < len;i++){
                TreeNode node = queue.poll();
                resLine.add(node.val);
                if(node.left!=null) queue.offer(node.left);
                if(node.right!=null) queue.offer(node.right);
            }
            res.add(resLine);
        }
        return res;
    }
}

226.翻转二叉树

这道题目二刷,但是还是没有一次通过,出现了输出和输入完全一样的问题,先附上错误代码,而后会以图的形式对比分析错误原因:

class Solution {
    public TreeNode invertTree(TreeNode root) {
        if(root==null) return null;
        swap(root.left,root.right);
        invertTree(root.left);
        invertTree(root.right);
        return root;
    }
    public void swap(TreeNode right,TreeNode left){
        TreeNode tempNode = right;
        right = left;
        left = tempNode;
    }
}

后面参考了答案,改写了swap方法,通过:

class Solution {
    public TreeNode invertTree(TreeNode root) {
        if(root==null) return null;
        swap(root);
        invertTree(root.left);
        invertTree(root.right);
        return root;
    }
    public void swap(TreeNode node){
        TreeNode tempNode = node.left;
        node.left = node.right;
        node.right = tempNode;
    }
}

swap方法中,一个是将待翻转节点的左右节点分别传入,一个是直接将待翻转节点传入。这两者有什么区别呢?为什么前者错了?
这其实是和方法传参的机制有关,我们都知道在Java中,对象是通过引用传递的。当你将一个对象作为参数传递给方法时,实际上是传递了一个指向该对象的引用的副本
那么第一个swap方法其实是分别创建了right和left的副本传入方法中进行交换
在这里插入图片描述
进入方法,创建一个tempNode引用指向right(副本)指向的实例对象
在这里插入图片描述
然后right(副本)引用指向left(副本)指向的实例对象

在这里插入图片描述
最后,left(副本)指向tempNode指向的实例对象
在这里插入图片描述
我们可以看出,这个方法只能将left和right指针的副本进行互换,不能对本身的right和left指针互换。
而第二个swap之所以正确,是因为直接将node的副本引用传入方法中
在这里插入图片描述
在这里插入图片描述
经过交换操作,最终完成了left和right位置的真正互换。

层序遍历

一定要记住最开始要判断root==null的情况

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> res = new ArrayList<List<Integer>>();//List是接口 无法实例化 因此只能实例化ArrayList
        if(root == null) return res;
        LinkedList<TreeNode> queue = new LinkedList<TreeNode>();//用来存放待弹出的节点
        queue.offer(root);
        while(!queue.isEmpty()){
            ArrayList<Integer> resLine = new ArrayList<Integer>();//存放每一行的结果
            int len = queue.size();
            for(int i=0;i < len;i++){
                TreeNode node = queue.poll();
                resLine.add(node.val);
                if(node.left!=null) queue.offer(node.left);
                if(node.right!=null) queue.offer(node.right);
            }
            res.add(resLine);
        }
        return res;
    }
}

对称二叉树

这道题没啥好说的 直接看卡哥视频 非常清晰
只总结一句话:每一个节点需要知道自己的左右节点是否对称才可以判断以自己为根节点的子树是都对称,从叶子节点向上不断返回左右节点对称判定结果的与,最终返回到根节点,得到最终结果。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public boolean isSymmetric(TreeNode root) {
        if(root == null) return false;
        return judge(root.right,root.left);

    }
    public boolean judge(TreeNode right,TreeNode left){
        if(right==null && left==null) return true;
        else if(right==null && left!=null) return false;
        else if(right!=null && left==null) return false;
        else if(right.val != left.val) return false;
        boolean out =  judge(right.right,left.left);
        boolean in =  judge(right.left,left.right);
        return out && in;
    } 
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值