随想录训练营Day15 | 107.二叉树的层次遍历 II, 226.翻转二叉树, 101. 对称二叉树

57 阅读3分钟

随想录训练营Day15 | 107.二叉树的层次遍历 II, 226.翻转二叉树, 101. 对称二叉树

标签: LeetCode闯关记


1. 107.二叉树的层次遍历 II

class Solution {
    public List<List<Integer>> levelOrderBottom(TreeNode root) {

        List<List<Integer>> list = new ArrayList<>();
        Deque<TreeNode> deque = new LinkedList<>();

        if(root == null){//出现问题: 忘记判断root所以抛出异常:java.lang.NullPointerException: Cannot read field "val" because the return value of "java.util.Deque.pollFirst()" is null'
            return list;
        }
        deque.addLast(root);
        while (! deque.isEmpty()){
            List<Integer> levelList = new ArrayList<>();//用一维数组来记录每一层的节点值
            int levelSize = deque.size();//用levelSize来记录每一层的个数,这样就不会分不清该层和下一层的元素
            while(levelSize > 0){
                TreeNode node = deque.peekFirst();
                levelList.add(deque.pop().val);

                if(node.left != null){
                    deque.addLast(node.left);
                }
                if(node.right != null){
                    deque.addLast(node.right);
                }
                levelSize--;
            }
            //完成一层遍历之后,将一维数组添加入二维数组list中
            list.add(levelList);
        }
        //反转list即可得到自底向上的层序遍历
        List<List<Integer>> result = new ArrayList<>();
        for (int i = list.size() - 1; i >= 0 ; i--) {
            result.add(list.get(i));
        }
        return result;
    }
}

2. 226.翻转二叉树

  • DFS: 前序遍历-递归法
class Solution {
    public TreeNode invertTree(TreeNode root) {
        if( root == null){
            return root;
        }
        //中
        swapChildren(root);
        //左
        invertTree(root.left);
        //右
        invertTree(root.right);

        return root;
    }
    private void swapChildren(TreeNode root){
        TreeNode temp = root.right;
        root.right = root.left;
        root.left = temp;
    }
}
  • BFS:层序遍历-用队列实现
//BFS-层序遍历-用队列实现
class Solution {
    public TreeNode invertTree(TreeNode root) {
        Deque<TreeNode> deque = new LinkedList<>();
        if( root == null){
            return root;
        }
        deque.add(root);
        while (! deque.isEmpty()){
            int len = deque.size();
            while (len-- > 0){
                TreeNode node = deque.pop();
                swapChildren(node);
                if(node.left != null){
                    deque.addLast(node.left);
                }
                if(node.right != null){
                    deque.addLast(node.right);
                }
            }
        }
        return root;
    }
    private void swapChildren(TreeNode root){
        TreeNode temp = root.right;
        root.right = root.left;
        root.left = temp;
    }
}

3. 101. 对称二叉树

  • 错解
class Solution {
    public boolean isSymmetric(TreeNode root) {
        return compare(root.left, root.right);

    }
    private boolean compare(TreeNode left, TreeNode right){

        //终止条件
        if(left == null && right != null){
            return false;
        }
        if (left != null && right == null){
            return false;
        }
        if(left == null && right == null){
            return true;
        }
        if(left.val != right.val){
            return false;
        }
        //比较外侧
        boolean compareOutside = compare(left.left, right.right);
        System.out.println("外侧的左边" + left.left);
        if(left.left != null){System.out.println("外侧的左边的节点值" + left.left.val);}
        System.out.println("外侧的右边" + right.right);
        if(right.right != null){System.out.println("外侧的右边的节点值" + right.right.val);}
        System.out.println("------");
        //比较内侧
        boolean compareInside = compare(left.right, right.left);
        System.out.println("内侧的左边" + left.right);
        if(left.right != null){System.out.println("内侧的左边的节点值" + left.right.val);}
        System.out.println("内侧的右边" + right.left);
        if(right.left != null){System.out.println("内侧的右边的节点值" + right.left.val);}
        System.out.println("------");
        System.out.println("------");

        return compareInside && compareInside;//发现错误:手误打了两个comapreInside (无语...)
    }
}
  • 正解
class Solution {
    public boolean isSymmetric(TreeNode root) {
        return compare(root.left, root.right);

    }
    private boolean compare(TreeNode left, TreeNode right){

        //终止条件
        if(left == null && right != null){
            return false;
        }
        if (left != null && right == null){
            return false;
        }
        if(left == null && right == null){
            return true;
        }
        if(left.val != right.val){
            return false;
        }
        //比较外侧
        boolean compareOutside = compare(left.left, right.right);

        //比较内侧
        boolean compareInside = compare(left.right, right.left);

        return compareOutside && compareInside;
    }
}

相关题目: 100.相同的数

class Solution {
    public boolean isSameTree(TreeNode p, TreeNode q) {
        return compare(p,q);
    }
    private boolean compare(TreeNode p, TreeNode q) {

        if (p == null && q != null) {
            return false;
        }
        if (p != null && q == null) {
            return false;
        }

        if (p == null && q == null) {
            return true;
        }
        if (p.val != q.val) {
            return false;
        }
        // 比较两树的左子树
        boolean compareLeft = compare(p.left, q.left);
        // 比较两树的右子树
        boolean compareRight = compare(p.right, q.right);
        return compareLeft && compareRight;
    }

}

相关题目:572. 另一棵树的子树

class Solution {
    public boolean isSubtree(TreeNode root, TreeNode subRoot) {
        //第一个递归,先判断两树是否相同
        if(isSameTree(root,subRoot)){
            return true;
        }
        //运行到此处,说明subroot != null;

        //现在利用第二个递归,来找root里面有没有subRoot

        //第二个递归的终止条件,root == null
        if(root == null){
            return false;
        }
        //第二个递归的每层递归操作: 1.判断是不是相同的树; 2.不是的话,看root的左子树或者右子树是不是和subRoot是相同的
        if(isSubtree(root.left,subRoot) || isSubtree(root.right, subRoot)){
            return true;
        }else{return false;}

    }

    //利用递归法判断是否为相同树
    private boolean isSameTree(TreeNode p, TreeNode q){
        //递归的终止条件
        if(p == null && q != null){
            return false;
        }
        if(p != null && q == null){
            return false;
        }
        if(p == null && q == null){
            return true;
        }
        if(p.val != q.val){
            return false;
        }
        boolean isSameLeftTree = isSameTree(p.left, q.left);
        boolean isSameRightTree = isSameTree(p.right, q.right);
        return isSameLeftTree && isSameRightTree;
    }
}

4. 总结

有点晕,待总结, 其实递归理解得还不到位,自己写肯定有问题,需要复习.