所用代码 java
二叉树的最大深度 LeetCode104
题目链接: 二叉树的最大深度 LeetCode104 - 简答
思路
深度指的是从上往下数,一层深度就是1,总共二叉树有几层,深度就是几。深度一般是前序遍历,而求高度一般是后续遍历。
递归法 DFS
class Solution {
public int maxDepth(TreeNode root) {
return traversal(root,0);
}
// 前序遍历
public int traversal(TreeNode node, int deep){
if (node == null) return deep;
// 每次进来就深度就 + 1
deep++;
int left = traversal(node.left, deep);
int right = traversal(node.right, deep);
return left > right ? left : right;
}
// 后续遍历 深度=高度
public int traversal1(TreeNode node){
if (node == null) return 0;
int left = traversal(node.left);
int right = traversal(node.right);
// 高度每次往上递增
int maxHeight = 1 + Math.max(left, right);
return maxHeight;
// return 1 + Math.max(traversal(node.left), traversal(node.right));
}
}
层序遍历 BFS
public int maxDepth(TreeNode root) {
int deep = 0;
Deque<TreeNode> deque = new ArrayDeque<>();
if (root != null) deque.offer(root);
while (!deque.isEmpty()){
// 每进入一层,深度加一
deep++;
int size = deque.size();
for (int i = 0; i < size; i++) {
TreeNode node = deque.poll();
if (node.left != null) deque.offer(node.left);
if (node.right != null) deque.offer(node.right);
}
}
return deep;
}
总结
一般来说求深度就可以看成求高度,然后就可以用后序遍历的方式进行递归,而且可以把代码写的很极简,一行就可以搞定,但是不建议这样写,因为只有写清楚过程我们才能知道遍历的顺序。另外本题层序遍历也是非常的清晰,但是会消耗更多的空间。
n叉树的最大深度 LeetCode559
题目链接:n叉树的最大深度 LeetCode559 - 简单
思路
同二叉树的一样
递归 BFS
class Solution {
public int maxDepth(Node root) {
return traversal(root);
}
public int traversal(Node node){
if (node == null) return 0;
// 这个必须令deep=0,以便孩子结点在往下搜索时deep一直增长
int deep = 0;
List<Node> children = node.children;
for (Node child : children){
int height = traversal(child);
deep = Math.max(deep, height);
}
return deep + 1;
}
}
层序遍历 DFS
class Solution {
public int maxDepth(Node root) {
int deep = 0;
Deque<Node> deque = new ArrayDeque<>();
if (root != null) deque.offer(root);
while (!deque.isEmpty()){
// 每遍历一层深度便加一
deep++;
int size = deque.size();
for (int i = 0; i < size; i++) {
Node node = deque.poll();
List<Node> children = node.children;
for (Node child : children){
deque.offer(child);
}
}
}
return deep;
}
}
总结
总感觉使用层序要简单一点,更符合人类的思考方式。
二叉树的最小深度 LeetCode111
题目链接:二叉树的最小深度 LeetCode111 - 简单
思路
和最大深度做法一样
递归法 DFS
class Solution {
public int minDepth(TreeNode root) {
return traversal(root);
}
public int traversal(TreeNode node){
if (node == null) return 0;
int left = traversal(node.left);
int right = traversal(node.right);
// 中 需要考虑往一边走的情况,也就是只有一个子树
if (node.left == null && node.right != null){
return right + 1;
}
if (node.left != null && node.right == null){
return left + 1;
}
int minDepth = Math.min(left, right) + 1;
return minDepth;
}
}
层序遍历BFS
class Solution {
public int minDepth(TreeNode root) {
int deep = 0;
Deque<TreeNode> deque = new ArrayDeque<>();
if (root != null) deque.offer(root);
while (!deque.isEmpty()){
int size = deque.size();
// 每进入一层,深度就+1
deep++;
for (int i = 0; i < size; i++) {
TreeNode node = deque.poll();
// 该结点为叶子结点就返回
// 因为我们是从上往下,从左往右遍历,出现叶子结点一定是最小的深度
if (node.left == null && node.right == null){
return deep;
}
if (node.left != null) deque.offer(node.left);
if (node.right != null) deque.offer(node.right);
}
}
return deep;
}
}
总结
求二叉树的最小深度和最大深度是差不多的,主要区别就是中结点的处理上,要注意什么是最小的深度,必须有子结点的才算,所以求最小深度有一个判断的过程。
完全二叉树的节点个数 LeetCode 222
题目链接:完全二叉树的节点个数 LeetCode 222 - 中等
思路
1、普遍二叉树的方法
class Solution {
int num = 0;
public int countNodes(TreeNode root) {
traversal(root);
return num;
}
public void traversal(TreeNode root){
if (root == null) return;
num++;
traversal(root.left);
traversal(root.right);
}
}
// 后序的写法,不用再定义一个num进行遍历
public int postTraversal(TreeNode root){
if (root == null) return 0;
int left = postTraversal(root.left);
int right = postTraversal(root.right);
// 结点数量 = 左孩子的结点数量 + 右孩子的结点数量 + 自己(1)
int num = left + right + 1;
return num;
}
2、利用完全二叉树的性质,除了最下边一层,上边是满二叉树满二叉树的结点个数为2^k - 1,k为深度,就不用把每一个结点都遍历完。
class Solution {
public int countNodes(TreeNode root) {
return CompleteTree(root);
}
public int CompleteTree(TreeNode node){
// 返回情况1:遇到空结点
if (node == null) return 0;
// 返回情况2:是完全二叉树的情况
TreeNode leftNode = node.left;
TreeNode rightNode = node.right;
int leftDepth = 0;
int rightDepth = 0;
// 计算左侧深度
while (leftNode != null){
leftNode = leftNode.left;
leftDepth++;
}
// 计算右侧深度
while (rightNode != null){
rightNode = rightNode.right;
rightDepth++;
}
// 判断两侧深度是否相等,相等则为满二叉树
if (leftDepth == rightDepth){
// 2<<1 2左移一位相等于2的2次方
// 根据下边,右边为2^0 左移增加位数
// 256 128 64 32 16 8 4 2 1
return (2 << leftDepth) - 1;
}
// 开始进行递归 - 后序
int leftNum = CompleteTree(node.left);
int rightNum = CompleteTree(node.right);
// 自己结点的数量 = 左子树数量 + 右子树数量 + 自己(1)
int num = leftNum + rightNum + 1;
return num;
}
}
总结
这个题考的是我们能否利用完全二叉树的性质来完成,完全二叉树只有底层不是满的,上层是满二叉树,而满二叉树可以快速的计算出结点的个数,就不用把所有的结点都遍历一遍。