题目来源

代码1(递归法)

java
/**
* 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 {
private int maxDiameter = 0;
public int diameterOfBinaryTree(TreeNode root) {
getDepth(root);
return maxDiameter;
}
//返回当前结点最大深度(左右子树最大深度+1)以及求左右子树最大深度之和(该结点最大直径)
private int getDepth(TreeNode node) {
if(node == null) return 0;
int leftDepth = getDepth(node.left);
int rightDepth = getDepth(node.right);
maxDiameter = Math.max(maxDiameter,leftDepth + rightDepth);
return Math.max(leftDepth, rightDepth)+1;
}
}
代码分析
直径:一个结点的,左子树最大深度 + 右子树最大深度
最大直径: 所有结点中,的最大的那个。
在求一个结点的深度时(max(left,right) + 1) ,顺便求出来该结点的直径
代码2(dfs迭代法,左右根后序遍历)

java
/**
* 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 {
public int diameterOfBinaryTree(TreeNode root) {
if(root == null) return 0;
int maxDiameter = 0;
Stack<Object[]> stack = new Stack<>(); // 存储:[节点, 是否访问过]
Map<TreeNode, Integer> depth = new HashMap<>();
stack.push(new Object[]{root,false});
while(!stack.isEmpty()) {
Object[] entry = stack.pop();
TreeNode node = (TreeNode) entry[0];
boolean isVisited = (boolean)entry[1];
if(!isVisited) {
// 首次弹出处理: 其实就是遍历顺序以及回退顺序处理
// 根放里边,然后是右,然后是左。
// 其实就是后续遍历,用于二次弹出回退计算处理
stack.push(new Object[]{node,true});
if(node.right!=null) stack.push(new Object[]{node.right,false});
if(node.left!=null) stack.push(new Object[]{node.left,false});
} else {
int leftDepth = depth.getOrDefault(node.left, 0);
int rightDepth = depth.getOrDefault(node.right, 0);
maxDiameter = Math.max(maxDiameter, leftDepth+rightDepth);
depth.put(node, Math.max(leftDepth,rightDepth)+1);
}
}
return maxDiameter;
}
}
代码分析
二次弹出,模拟的是 : 左右根后序遍历,核心是先处理左右子树的计算,再处理根结点
哈希表存储结点深度,是为了获取左右子树结点的深度,用于计算。
栈的存储的是 : Object[] 用于放 结点 + 结点访问情况(是否访问过)
当然也可以用哈希表来存储。 Map<TreeNode, boolean>