一个人的朝圣 — LeetCode打卡第16天
知识总结
今天接着继续二叉树. 一定要审题, 最后一道完全二叉树的节点个数完全看错了题目.
学会一种表达, 我们用位移运算来代替幂运算
2 << 1 等价于 2 ^ 2 = 4
Leetcode 104. 二叉树的最大深度
题目说明
给定一个二叉树,找出其最大深度。
代码说明
class Solution {
public int maxDepth(TreeNode root) {
if(root == null) return 0;
return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
}
}
Leetcode 559. N 叉树的最大深度
题目说明
给定一个 N 叉树,找到其最大深度。
最大深度是指从根节点到最远叶子节点的最长路径上的节点总数。
代码说明
用递归和迭代都写了一下, 发现有时候递归反而更难想到. 其实思路和上面的题目一模一样. 确定终止条件, 然后确定循环条件.
递归法
class Solution {
public int maxDepth(Node root) {
if (root == null) return 0;
int maxDepth = 0;
for(Node child : root.children){
maxDepth = Math.max(maxDepth(child), maxDepth);
}
return maxDepth + 1;
}
}
迭代法
class Solution {
public int maxDepth(Node root) {
if (root == null) return 0;
int maxDepth = 0;
Queue<Node> queue = new LinkedList<>();
queue.offer(root);
while(!queue.isEmpty()){
int len = queue.size();
while(len > 0){
Node cur = queue.poll();
for(Node child : cur.children){
if(child != null){
queue.offer(child);
}
}
len--;
}
maxDepth++;
}
return maxDepth;
}
}
Leetcode 111. 二叉树的最小深度
题目说明
给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
代码说明
这样要注意, 叶子节点的定义, 不是遇到null就代表该节点是叶子节点. 需要递归时好好判断.
迭代法
这个思路反而更加清晰, 一层一层遍历, 遇到的第一个叶子节点就直接返回. 此时该节点的深度一定是最小的
class Solution {
public int minDepth(TreeNode root) {
if(root == null) return 0;
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
int deepth = 0;
while(!queue.isEmpty()){
int len = queue.size();
while(len> 0){
TreeNode cur = queue.poll();
if(cur.left == null && cur.right == null){
return deepth + 1;
}
if(cur.left != null) queue.offer(cur.left);
if(cur.right != null) queue.offer(cur.right);
len--;
}
deepth++;
}
return deepth;
}
}
递归法
需要分类讨论左子树和右子树是否为空的情况
class Solution {
public int minDepth(TreeNode root) {
if(root == null) return 0;
if(root.left == null && root.right == null){
return 1;
}
int m1 = minDepth(root.left);
int m2 = minDepth(root.right);
// 有一方为空, 为空的的深度就是0, 所以可以直接相加
if(root.left== null || root.right == null){
return m1 + m2 + 1;
}
// 左右都不为空, 则取最小值 + 1
return Math.min(m1, m2) + 1;
}
}
Leetcode 222. 完全二叉树的节点个数
题目说明
给你一棵 完全二叉树 的根节点 root ,求出该树的节点个数。
完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1 2 h 1~ 2^h 1 2h 个节点。
代码说明
题目已知的条件是给了一个完全的二叉树, 让我们去求树的节点个数. 正常的可以使用通用的遍历直接求.
但是这里我们做了一个优化.
如果我们发现给树一直到左和一直到右的深度相同, 则该子树为一个满二叉树, 满二叉树的节点数量公式为
n u m = 2 d e p t h − 1 num = 2 ^ {depth} -1 num=2depth−1
这样可以减少遍历的次数
class Solution {
public int countNodes(TreeNode root) {
if(root == null) return 0;
int leftDepth= 0, rightDepth = 0;
TreeNode l = root.left;
TreeNode r = root.right;
while(l != null){
l = l.left;
leftDepth++;
}
while(r != null){
r = r.right;
rightDepth++;
}
if(leftDepth == rightDepth){
return (2 << leftDepth) - 1;
}
return countNodes(root.left) + countNodes(root.right) + 1;
}
}