一、二叉树的最大深度
递归解法 + 后序遍历(DFS)
class Solution {public int maxDepth(TreeNode root) {if (root == null) return 0;return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;}
}
算法解析:
- 终止条件: 当 root 为空,说明已越过叶节点,因此返回 深度 0 。
- 递推工作: 本质上是对树做后序遍历。
- 计算节点 root 的 左子树的深度 ,即调用 maxDepth(root.left)。
- 计算节点 root 的 右子树的深度 ,即调用 maxDepth(root.right)。
- 返回值: 返回 此树的深度 ,即 max(maxDepth(root.left), maxDepth(root.right)) + 1。
层序遍历
class Solution {public int maxDepth(TreeNode root) {if (root == null) return 0;List<TreeNode> queue = new LinkedList<>() {{ add(root); }}, tmp;int res = 0;while (!queue.isEmpty()) {tmp = new LinkedList<>();for(TreeNode node : queue) {if (node.left != null) tmp.add(node.left);if (node.right != null) tmp.add(node.right);}queue = tmp;res++;}return res;}
}
二、二叉树的最小深度
参考111. 二叉树的最小深度 - 力扣(LeetCode)
鄙人思路是使用层序遍历,找到第一个左右子树都为空的节点返回,但是对比了一下递归的代码,故还是决定将递归代码记录,
递归
class Solution {public int minDepth(TreeNode root) {if(root == null) return 0;//这道题递归条件里分为三种情况//1.左孩子和有孩子都为空的情况,说明到达了叶子节点,直接返回1即可if(root.left == null && root.right == null) return 1;//2.如果左孩子和由孩子其中一个为空,那么需要返回比较大的那个孩子的深度 int m1 = minDepth(root.left);int m2 = minDepth(root.right);//这里其中一个节点为空,说明m1和m2有一个必然为0,所以可以返回m1 + m2 + 1;if(root.left == null || root.right == null) return m1 + m2 + 1;//3.最后一种情况,也就是左右孩子都不为空,返回最小深度+1即可return Math.min(m1,m2) + 1; }
}
三、完全二叉树的节点个数
参考222. 完全二叉树的节点个数 - 力扣(LeetCode)
完全二叉树的定义:它是一棵空树或者它的叶子节点只出在最后两层,若最后一层不满则叶子节点只在最左侧。
利用完全二叉树特点,最左侧最底层子树一定是该二叉树最深的节点 ->求出高度/深度
如果满二叉树的层数为h,则总节点数为:2^h - 1.
那么我们来对 root 节点的左右子树进行高度统计,分别记为 left 和 right,有以下两种结果:
left == right。这说明,左子树一定是满二叉树,因为节点已经填充到右子树了,左子树必定已经填满了。所以左子树的节点总数我们可以直接得到,是 2^left - 1,加上当前这个 root 节点,则正好是 2^left。再对右子树进行递归统计。
left != right。说明此时最后一层不满,但倒数第二层已经满了,可以直接得到右子树的节点个数。同理,右子树节点 +root 节点,总数为 2^right。再对左子树进行递归查找
class Solution {public int countNodes(TreeNode root) {if(root == null){return 0;} int left = countLevel(root.left);int right = countLevel(root.right);if(left == right){ //Math.pow()方法返回的是double类型,所以要使用int()进行转化// 1<<left == (int) Math.pow(2,left)return countNodes(root.right) + (1<<left);}else{return countNodes(root.left) + (1<<right);}}private int countLevel(TreeNode root){int level = 0;while(root != null){level++;root = root.left;}return level;}
}
四、小结
做了几道二叉树的题发现,对二叉树的逻辑部分处理,大部分都离不开,node,left,right;或者像对称树的案例,再多两个分支,然后进行重复判断(递归或者while循环)
对称树