代码随想录算法训练营第十五天| 二叉树的层序遍历、226. 翻转二叉树、101. 对称二叉树

0102.二叉树的层序遍历 文章解释

自己看到题目的第一想法

    当我们拿到一个数的头节点开始遍历的时候, 我们在单次循环中可以拿到三个节点: 头节点、头节点的左节点、头节点的右节点. 这时候是可以得到层序遍历的结果的. 但是当深度到达第三层的时候, 左侧的节点, 就无法链接到右侧的节点. 这可怎么办呢? 拿一个独立的节点去记录分叉的位置吗? 如果深度继续往下, 分叉点变得越来越多. 有办法通过迭代的方式记录这些分叉点吗?

   头好大T_T 还是先看视频吧.

看完代码随想录之后的想法

   原来只要拿一个队列保存住当前深度的所有节点, 遍历完成后生成下一层的节点列表就可以. 还是挺简单的.

102. 二叉树的层序遍历

给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。

示例 1:

输入:root = [3,9,20,null,null,15,7]
输出:[[3],[9,20],[15,7]]

示例 2:

输入:root = [1]
输出:[[1]]

示例 3:

输入:root = []
输出:[]

提示:

  • 树中节点数目在范围 [0, 2000]
  • -1000 <= Node.val <= 1000
/**
 * 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>> result = new ArrayList<>();
        if (root == null) {
            return result;
        }
        LinkedList<TreeNode> nodes = new LinkedList<>();
        List<Integer> sameDepthNodeValues = null;
        TreeNode node = null;
        int size = 0;;

        nodes.addLast(root);
        while (!nodes.isEmpty()) {
            size = nodes.size();
            sameDepthNodeValues = new ArrayList<>();
            while (size-- > 0) {
                node = nodes.pop();
                if (node.left != null) {
                    nodes.addLast(node.left);
                }
                if (node.right != null) {
                    nodes.addLast(node.right);
                }
                sameDepthNodeValues.add(node.val);
            }
            result.add(sameDepthNodeValues);
        }
        return result;
    }
}

107. 二叉树的层序遍历 II

给你二叉树的根节点 root ,返回其节点值 自底向上的层序遍历 。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)

输入:root = [3,9,20,null,null,15,7]
输出:[[15,7],[9,20],[3]]

示例 2:

输入:root = [1]
输出:[[1]]

示例 3:

输入:root = []
输出:[]

提示:

  • 树中节点数目在范围 [0, 2000]
  • -1000 <= Node.val <= 1000
/**
 * 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>> levelOrderBottom(TreeNode root) {
        List<List<Integer>> result = new ArrayList<>();
        if (root == null) {
            return result;
        }

        LinkedList<TreeNode> nodes = new LinkedList<>();
        List<Integer> sameDephNodeValues = null;
        TreeNode node = null;
        int size;


        nodes.addLast(root);
        while (!nodes.isEmpty()) {
            size = nodes.size();
            sameDephNodeValues = new ArrayList<>();
            while (size-- > 0) {
                node = nodes.pop();
                if (node.left != null) {
                    nodes.addLast(node.left);
                }
                if (node.right != null) {
                    nodes.addLast(node.right);
                }
                sameDephNodeValues.add(node.val);
            }
            result.add(sameDephNodeValues);
        }

        for (int i = 0; i < result.size()/2; i++) {
            sameDephNodeValues = result.get(i);
            result.set(i, result.get(result.size() - 1 - i));
            result.set(result.size() - 1 - i, sameDephNodeValues);
        }
        return result;
    }
}

 199. 二叉树的右视图

给定一个二叉树的 根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。

示例 1:

输入: [1,2,3,null,5,null,4]
输出: [1,3,4]

示例 2:

输入: [1,null,3]
输出: [1,3]

示例 3:

输入: []
输出: []
/**
 * 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;
 *     }
 * }
 */
// 不是很高效的解法: 评分排名才 80%
class Solution {
    public List<Integer> rightSideView(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        if (root == null) {
            return result;
        }
        LinkedList<TreeNode> nodes = new LinkedList<>();
        TreeNode node;
        int size;
        
        nodes.addLast(root);
        while (!nodes.isEmpty()) {
            size = nodes.size();
            while (size-- > 0){
                node = nodes.pop();
                if (size == 0) {
                    result.add(node.val);
                }
                if (node.left != null) {
                    nodes.addLast(node.left);
                }
                if (node.right != null) {
                    nodes.addLast(node.right);
                }
            }
        }
        return result;
    }
}

637. 二叉树的层平均值

给定一个非空二叉树的根节点 root , 以数组的形式返回每一层节点的平均值。与实际答案相差 10-5 以内的答案可以被接受。

示例 1:

输入:root = [3,9,20,null,null,15,7]
输出:[3.00000,14.50000,11.00000]
解释:第 0 层的平均值为 3,第 1 层的平均值为 14.5,第 2 层的平均值为 11 。
因此返回 [3, 14.5, 11] 。

示例 2:

输入:root = [3,9,20,15,7]
输出:[3.00000,14.50000,11.00000]

提示:

  • 树中节点数量在 [1, 10^4] 范围内
  • -2^31 <= Node.val <= 2^31 - 1
/**
 * 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<Double> averageOfLevels(TreeNode root) {
        List<Double> result = new ArrayList<>();
        if (root == null) {
            return result;
        }
        double sum;
        LinkedList<TreeNode> nodes = new LinkedList<>();
        TreeNode node;
        int size;
        int nodeSize;
        nodes.addLast(root);
        while (!nodes.isEmpty()) {
            size = nodeSize = nodes.size();
            sum = 0;
            while (size-- > 0) {
                node = nodes.pop();
                sum += node.val;
                if (node.left != null) {
                    nodes.add(node.left);
                }
                if (node.right != null) {
                    nodes.add(node.right);
                }
            }
            result.add(sum/nodeSize);
        }
        return result;
    }
}
// 递归法: 并没有更快
class Solution {
    public List<Double> averageOfLevels(TreeNode root) {
        List<Double> result = new ArrayList<>();
        if (root == null) {
            return result;
        }
        Map<Integer, Double> numberSum = new HashMap<>();
        Map<Integer, Integer> numberCount = new HashMap<>();
        averageOfLevelsRecursion(root, numberSum, numberCount, 0);
        for (int i = 0; i < numberSum.size(); i++) {
            result.add(numberSum.get(i)/numberCount.get(i));
        }
        return result;
    }

    private void averageOfLevelsRecursion(TreeNode node, Map<Integer, Double> sums, Map<Integer, Integer> counts, int depth) {
        double sum = sums.getOrDefault(depth, 0.0);
        sum += node.val;
        sums.put(depth, sum);
        counts.put(depth, counts.getOrDefault(depth, 0) + 1);
        
        if (node.left != null) {
            averageOfLevelsRecursion(node.left, sums, counts, depth + 1);
        }
        if (node.right != null) {
            averageOfLevelsRecursion(node.right, sums, counts, depth + 1);
        }
    }
}

429. N 叉树的层序遍历

// 二叉树的层序遍历复制过来改一两句代码就行了, 效率尚可. 92%
/*
// Definition for a Node.
class Node {
    public int val;
    public List<Node> children;

    public Node() {}

    public Node(int _val) {
        val = _val;
    }

    public Node(int _val, List<Node> _children) {
        val = _val;
        children = _children;
    }
};
*/
class Solution {
    public List<List<Integer>> levelOrder(Node root) {
        List<List<Integer>> result = new ArrayList<>();
        if (root == null) {
            return result;
        }
        LinkedList<Node> nodes = new LinkedList<>();
        List<Integer> sameDepthNodeValues = null;
        Node node = null;
        int size = 0;;

        nodes.addLast(root);
        while (!nodes.isEmpty()) {
            size = nodes.size();
            sameDepthNodeValues = new ArrayList<>();
            while (size-- > 0) {
                node = nodes.pop();
                if (node.children != null) {
                    nodes.addAll(node.children);
                }
                sameDepthNodeValues.add(node.val);
            }
            result.add(sameDepthNodeValues);
        }
        return result;
    }
}

 515. 在每个树行中找最大值

// 因为没有排序, 所以需要遍历所有的元素. 效率一般: 90%
/**
 * 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<Integer> largestValues(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        if (root == null) {
            return result;
        }
        ArrayDeque<TreeNode> nodes = new ArrayDeque<>();
        TreeNode node = null;
        int size;
        Integer maxNumber;
        nodes.addLast(root);
        while (!nodes.isEmpty()) {
            size = nodes.size();
            maxNumber = null;
            while (size-- > 0) {
                node = nodes.pop();
                if (maxNumber == null) {
                    maxNumber = node.val;
                } else if (node.val > maxNumber) {
                    maxNumber = node.val;
                }
                if (node.left != null) {
                    nodes.addLast(node.left);
                }
                if (node.right != null) {
                    nodes.addLast(node.right);
                }
            }
            result.add(maxNumber);
        }
        return result;
    }
}

116. 填充每个节点的下一个右侧节点指针

117. 填充每个节点的下一个右侧节点指针 II

/*
// Definition for a Node.
class Node {
    public int val;
    public Node left;
    public Node right;
    public Node next;

    public Node() {}
    
    public Node(int _val) {
        val = _val;
    }

    public Node(int _val, Node _left, Node _right, Node _next) {
        val = _val;
        left = _left;
        right = _right;
        next = _next;
    }
};
*/
// 效率很差: 83.7%
class Solution {
    public Node connect(Node root) {
        if (root == null) {
            return null;
        }
        ArrayDeque<Node> nodes = new ArrayDeque<>();
        Node node = null;
        Node lastNode = null;
        nodes.addLast(root);
        while (!nodes.isEmpty()) {
            int size = nodes.size();
            lastNode = null;
            while (size-- > 0) {
                node = nodes.pop();
                if (node.left != null) {
                    nodes.addLast(node.left);
                }
                if (node.right != null) {
                    nodes.addLast(node.right);
                }
                if (lastNode == null) {
                    lastNode = node;
                } else {
                    lastNode.next = node;
                    lastNode = lastNode.next;
                }
            }
        }
        return root;
    }
}

104. 二叉树的最大深度 

/**
 * 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 int maxDepth(TreeNode root) {
        LinkedList<TreeNode> nodes = new LinkedList<>();
        if (root == null) {
            return 0;
        }
        nodes.addLast(root);
        TreeNode node = null;
        int depth = 0;
        while (!nodes.isEmpty()) {
            int size = nodes.size();
            depth++;
            while(size-- > 0) {
                node = nodes.pop();
                if (node.left != null) {
                    nodes.addLast(node.left);
                }
                if (node.right != null) {
                    nodes.addLast(node.right);
                }
            }
        }
        return depth;
    }
}
/**
 * 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 int maxDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }
        if (root.left == null && root.right == null) {
            return 1;
        }
        return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
    }
}

111. 二叉树的最小深度

/**
 * 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;
 *     }
 * }
 */
// 这里用迭代法效率很高: 99.99%
class Solution {
    public int minDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }

        LinkedList<TreeNode> nodes = new LinkedList<>();
        nodes.addLast(root);
        TreeNode node = null;
        int depth = 0;
        while (!nodes.isEmpty()) {
            int size = nodes.size();
            depth++;
            while (size-- > 0) {
                node = nodes.pop();
                if (node.left == null && node.right == null) {
                    return depth;
                }
                if (node.left != null) {
                    nodes.addLast(node.left);
                }
                if (node.right != null) {
                    nodes.addLast(node.right);
                }
            }
        }
        return depth;
    }
}
/**
 * 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;
 *     }
 * }
 */
// 递归法: 效率极低 60%
class Solution {
    public int minDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }

        int leftNodeDepth = minDepth(root.left);
        int rightNodeDepth = minDepth(root.right);
        
        if (leftNodeDepth > 0 && rightNodeDepth == 0) {
            return leftNodeDepth + 1;
        } else if (leftNodeDepth == 0 && rightNodeDepth > 0) {
            return rightNodeDepth + 1;
        } else {
            return Math.min(leftNodeDepth, rightNodeDepth) + 1;
        }
    }
}

[LeetCode] 226. 翻转二叉树

[LeetCode] 226. 翻转二叉树 文章解释

[LeetCode] 226. 翻转二叉树 视频解释

给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。

/**
 * 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 TreeNode invertTree(TreeNode root) {
        if(root == null) {
            return null;
        }
        TreeNode node = root.left;
        root.left = root.right;
        root.right = node;
        invertTree(root.left);
        invertTree(root.right);
        return root;
    }
}

 

/**
 * 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 TreeNode invertTree(TreeNode root) {
        if(root == null) {
            return null;
        }
        invertTree(root.left);
        invertTree(root.right);
        TreeNode node = root.left;
        root.left = root.right;
        root.right = node;
        return root;
    }
}
// 中序遍历
/**
 * 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 TreeNode invertTree(TreeNode root) {
        if(root == null) {
            return null;
        }
        invertTree(root.right);// root.left
        TreeNode node = root.left;
        root.left = root.right;
        root.right = node;
        invertTree(root.right);// root.left
        return root;
    }
}
// 迭代法: 效率极高 100%
class Solution {
    public TreeNode invertTree(TreeNode root) {
        if(root == null) {
            return null;
        }
        LinkedList<TreeNode> nodes = new LinkedList<>();
        TreeNode node;
        TreeNode temp;
        nodes.addLast(root);

        while (!nodes.isEmpty()) {
            int size = nodes.size();
            while (size-- > 0) {
                node = nodes.pop();
                temp = node.left;
                node.left = node.right;
                node.right = temp;
                if (node.left != null) {
                    nodes.addLast(node.left);
                }
                if (node.right != null) {
                    nodes.addLast(node.right);
                }
            }
        }
        return root;
    }
}
// 迭代法
class Solution {
    public TreeNode invertTree(TreeNode root) {
        if(root == null) {
            return null;
        }
        LinkedList<TreeNode> nodes = new LinkedList<>();
        TreeNode node = root;
        TreeNode temp = null;

        while (node != null || !nodes.isEmpty()) {
            if (node != null) {
                nodes.push(node);
                node = node.left;
            } else {
                node = nodes.pop();
                temp = node.left;
                node.left = node.right;
                node.right = temp;
                node = node.left;
            }
        }
        return root;
    }
}
// 统一风格迭代法
class Solution {
    public TreeNode invertTree(TreeNode root) {
        if(root == null) {
            return null;
        }
        LinkedList<TreeNode> nodes = new LinkedList<>();
        nodes.push(root);
        TreeNode node;
        TreeNode temp;
        while (!nodes.isEmpty()) {
            node = nodes.pop();
            if (node != null) {
                if (node.right != null) {
                    nodes.push(node.right);
                }
                if (node.left != null) {
                    nodes.push(node.left);
                }
                nodes.push(node);
                nodes.push(null);
            } else {
                node = nodes.pop();
                temp = node.left;
                node.left = node.right;
                node.right = temp;
            }
        }
        return root;
    }
}

[LeetCode] 101. 对称二叉树

[LeetCode] 101. 对称二叉树 文章解释

[LeetCode] 101. 对称二叉树 视频解释

给你一个二叉树的根节点 root , 检查它是否轴对称。

示例 1:

输入:root = [1,2,2,3,4,4,3]
输出:true

示例 2:

输入:root = [1,2,2,null,3,null,3]
输出:false

提示:

  • 树中节点数目在范围 [1, 1000]
  • -100 <= Node.val <= 100
// 递归法
class Solution {
    public boolean isSymmetric(TreeNode root) {
        if (root == null) {
            return true;
        }
        return isSymmetric(root.left, root.right);
    }

    private boolean isSymmetric(TreeNode left, TreeNode right) {
        if (left == null && right == null) {
            return true;
        } else if (left == null && right != null) {
            return false;
        } else if (right == null) {
            return false;
        } else if (left.val != right.val) {
            return false;
        }
        return isSymmetric(left.left, right.right)
                && isSymmetric(left.right, right.left);
    }
}
// 迭代法: 效率一般 17.7%...
class Solution {
    public boolean isSymmetric(TreeNode root) {
        if (root == null) {
            return true;
        }
        Stack<TreeNode> nodes = new Stack<>();
        nodes.push(root.right);
        nodes.push(root.left);
        TreeNode left;
        TreeNode right;
        while (!nodes.isEmpty()) {
            left = nodes.pop();
            right = nodes.pop();
            if (left == null && right == null) {
               continue;
            } else if (left == null && right != null) {
                return false;
            } else if (right == null) {
                return false;
            } else if (left.val != right.val) {
                return false;
            }
            nodes.push(left.left);
            nodes.push(right.right);
            nodes.push(left.right);
            nodes.push(right.left);
        }
        return true;
    }   
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值