最大深度问题
用代码表示就是:
int depth = 1 + max(leftDepth, rightDepth);
而对于3,则是左右子树深度最大的那个然后再+1,具体谁更大,则不必关心
那什么时候结束呢,这里仍然是root == null返回0就行了。至于入参,自然是要处理的子树的根节点root,
而返回值则是当前root所在子树的最大高度。所以合在一起就是:
public int maxDepth(TreeNode root) {
if(root == null) {
return 0;
}
int leftHeight = maxDepth(root.left);
int rightHeight = maxDepth(root.right);
return Math.max(leftHeight, rightHeight) + 1;
}
层序遍历:
public int maxDepth(TreeNode root) {
if (root == null) {
return 0;
}
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.offer(root);
int ans = 0;
while (!queue.isEmpty()) {
//size表示某一层的所有元素数
int size = queue.size();
//size=0 表示一层访问完了
while (size > 0) {
TreeNode node = queue.poll();
if (node.left != null) {
queue.offer(node.left);
}
if (node.right != null) {
queue.offer(node.right);
}
size--;
}
ans++;
}
return ans;
}
判断平衡树
- 当节点root 左 / 右子树的高度差 < 2,则返回节点 root 的左右子树中最大高度加 1 ( max(left, right) + 1 );参考上面的高度和深度的对比图思考一下,这里为什么是最大高度?
- 当节点root 左 / 右子树的高度差 ≥2 :则返回 -1 ,代表 此子树不是平衡树
代码:
public boolean isBalance(TreeNode root) {
return height(root) >= 0;
}
public int height(TreeNode root) {
if (root == null) {
return 0;
}
int leftHeight = height(root.left);
int rightHeight = height(root.right);
if (leftHeight == -1 || rightHeight == -1 || Math.abs(leftHeight - rightHeight) > 1) {
return -1;
}else {
return Math.max(leftHeight, rightHeight) + 1;
}
}
最小深度
最小深度是从根节点到最近叶子节点的最短路径上的节点数量,也就是最小深度的一层必须要有叶子结点,因此不能直接用。
这里的核心问题仍然是分析终止条件:
- 如果左子树为空,右子树不为空,说明最小深度是 1 + 右子树的深度。
- 反之,右子树为空,左子树不为空,最小深度是 1 + 左子树的深度。
最后如果左右子树都不为空,返回左右子树深度最小值 + 1 。
代码如下:
递归:
public int minDepth(TreeNode root) {
if (root == null) {
return 0;
}
if (root.left == null && root.right == null) {
return 1;
}
int min_depth = Integer.MAX_VALUE;
if (root.left != null) {
min_depth = Math.min(minDepth(root.left), min_depth);
}
if (root.right != null) {
min_depth = Math.min(minDepth(root.right), min_depth);
}
return min_depth + 1;
}
层序遍历:
public int minDepth(TreeNode root) {
if (root == null) {
return 0;
}
int minDepth = 0;
LinkedList<TreeNode> queue = new LinkedList<TreeNode>();
queue.add(root);
while (queue.size() > 0) {
//获取当前队列的长度,这个长度相当于 当前这一层的节点个数
int size = queue.size();
minDepth++;
for (int i = 0; i < size; ++i) {
TreeNode t = queue.remove();
if (t.left == null && t.right == null) {
return minDepth;
}
if (t.left != null) {
queue.add(t.left);
}
if (t.right != null) {
queue.add(t.right);
}
}
}
return 0;
}
N叉树的最大深度
这道题就是将二叉树换成了N叉树,不同点就在于N叉树结点比较多,我们使用List存,遍历时用for即可
N叉树的定义:
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;
}
}
代码:
public int maxDepth(Node root) {
if (root == null) {
return 0;
}else if (root.children.isEmpty()) {
return 1;
}else {
List<Integer> heights = new LinkedList<>();
for (Node item : root.children) {
heights.add(maxDepth(item));
}
return Collections.max(heights) + 1;
}
}