一:求二叉树的最大深度
方法一:利用外部变量+遍历方法
* 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 {
int res=0;
int depth=0;
public int maxDepth(TreeNode root) {
traverse(root);
return res;
}
//从头到尾遍历一遍
void traverse(TreeNode root){
if(root==null) return;
//前序位置
depth++;
if(root.left==null&&root.right==null){
res=Math.max(depth,res);
}
traverse(root.left);
traverse(root.right);
//后序位置
depth--;
}
}
方法二:利用子问题答案推出原问题答案(后序遍历)
class Solution {
public int maxDepth(TreeNode root) {
if(root==null) return 0;
int leftMax=maxDepth(root.left);
int rightMax=maxDepth(root.right);
return 1+Math.max(leftMax,rightMax);
}
}
方法一的应用:打印节点在哪一层
void traverse(TreeNode root,int level){
if(root==null) return;
printf("节点%s 在第%d层",root,level);
traverse(root.left,level+1);
traverse(root.right,level+1);
}
traverse(root,1);
方法二的应用:打印节点左右子树各有多少个节点
//计算二叉树节点总数
int count(TreeNode root){
if(root==null) return 0;
int leftCount=count(root.left);
int rightCount=count(root.right);
printf("节点%s,左子树节点数%d,右子树节点数%d",root,leftCount,rightCount);
return 1+leftCount+rightCount;
}
二:求二叉树的最长直径即该节点左右子树最大深度之和
方法一:外部变量+遍历方法(前序位置)+最大深度
class Solution {
//最大直径长度
int maxDiameter=0;
public int diameterOfBinaryTree(TreeNode root) {
traverse(root);
return maxDiameter;
}
void traverse(TreeNode root){
if(root==null) return;
int leftMax=maxDepth(root.left);
int rightMax=maxDepth(root.right);
int myDiameter=leftMax+rightMax;
maxDiameter=Math.max(maxDiameter,myDiameter);
// 以上属于前序位置
traverse(root.left);
traverse(root.right);
}
public int maxDepth(TreeNode root){
if(root==null) return 0;
int leftMax=maxDepth(root.left);
int rightMax=maxDepth(root.right);
return 1+Math.max(leftMax,rightMax);
}
}
方法二:后序位置获取左右子树的最大深度
class Solution {
//最大直径长度
int maxDiameter=0;
public int diameterOfBinaryTree(TreeNode root) {
maxDepth(root);
return maxDiameter;
}
public int maxDepth(TreeNode root){
if(root==null) return 0;
int leftMax=maxDepth(root.left);
int rightMax=maxDepth(root.right);
int myDiameter=leftMax+rightMax;
maxDiameter=Math.max(maxDiameter,myDiameter);
return 1+Math.math(leftMax,rightMax);
}
}
层序遍历
// 输入一棵二叉树的根节点,层序遍历这棵二叉树
void levelTraverse(TreeNode root) {
if (root == null) return;
Queue<TreeNode> q = new LinkedList<>();
q.offer(root);
// 从上到下遍历二叉树的每一层
while (!q.isEmpty()) {
int sz = q.size();
// 从左到右遍历每一层的每个节点
for (int i = 0; i < sz; i++) {
TreeNode cur = q.poll();
// 将下一层节点放入队列
if (cur.left != null) {
q.offer(cur.left);
}
if (cur.right != null) {
q.offer(cur.right);
}
}
}
}
class Solution {
List<List<Integer>> res = new ArrayList<>();
List<List<Integer>> levelTraverse(TreeNode root) {
if (root == null) {
return res;
}
// root 视为第 0 层
traverse(root, 0);
return res;
}
void traverse(TreeNode root, int depth) {
if (root == null) {
return;
}
// 前序位置,看看是否已经存储 depth 层的节点了
if (res.size() <= depth) {
// 第一次进入 depth 层
res.add(new LinkedList<>());
}
// 前序位置,在 depth 层添加 root 节点的值
res.get(depth).add(root.val);
traverse(root.left, depth + 1);
traverse(root.right, depth + 1);
}
}