二叉树相关
力扣104 二叉树最大深度 普通递归遍历 外置两个高度变量
int depth = 0;
int maxDepth = 0;
public int maxDepth(TreeNode root) {
traverse(root);
return maxDepth;
}
public void traverse(TreeNode root){
if(root == null){
return;
}
depth++;
if(root.right == null && root.left == null){
maxDepth = maxDepth>depth?maxDepth:depth;
// 到达叶子节点 记录最大深度
depth--;
return;
// 向上回溯 depth--
}
traverse(root.left);
traverse(root.right);
// 左右都执行完 执行到这一步说明
// root.left 与 root.right 至少有一个不为空
// root 自己已经在depth中++过了
// 向上回溯 depth--
//(由于最底层的也会在访问root时(root不为空)做depth++
// 在return 的时候做depth--)
// 所以回溯到当前递归函数 depth 合法
depth--;
return;
}
力扣 104 递归遍历2 外置两个高度变量
int depth = 0;
int maxDepth = 0;
public int maxDepth(TreeNode root) {
maxDepth = traverse(root);
return maxDepth;
}
public int traverse(TreeNode root){
if(root == null){
return 0;
}
int left = traverse(root.left);
int right = traverse(root.right);
maxDepth = left>=right?left:right;
maxDepth++;
// 访问root,高度+1
return maxDepth;
}
二叉树求最大深度 只外置一个高度变量
1、定义一个全局变量hight,初始值为0,用于存储当前找到的最大深度。
2、maxDepth方法是主入口,接收一个TreeNode类型的根节点root。它首先初始化firstHight为0,然后调用traverseMaxDepth方法来遍历二叉树并计算最大深度。
3、traverseMaxDepth方法是递归函数,接收两个参数:当前节点root和当前深度depth。
4、如果root为空,返回depth,表示已经到达了该分支的末尾。
访问root后,depth加1,表示深入一层。
5、如果root是叶子节点(左右子节点都为空),更新hight为hight和depth中的较大值,然后depth减1,回溯到上一层。
6、如果root不是叶子节点,递归遍历左右子节点,将depth传递给子节点的遍历,确保每次递归调用时depth都是从父节点传来的当前深度。
7、递归返回后,depth减1,表示回溯到父节点。
8、这个算法通过递归遍历整个二叉树,每次遇到新的最大深度时更新hight,最终maxDepth方法返回的就是最大深度。
/*计算最大深度: 递归 + 回溯 外置1个高度变量*/
static int hight = 0;
public static int maxDepth(TreeNode root) {
int firstHight = 0;
traverseMaxDepth(root, firstHight);
return hight;
}
public static int traverseMaxDepth(TreeNode root, int depth) {
if (root == null) {
return depth;
}
// 访问root
depth++;
if (root.left == null && root.right == null) {
// root 为叶子
hight = Math.max(hight, depth);
// 叶子节点 向上回溯 depth减一
depth--;
return depth;
}
// root 非叶子
depth = traverseMaxDepth(root.left, depth);
// 若root.left为空 则depth不变
// 若root.left无左右子树 则depth++ 再--,仍为root函数执行前的depth参数
// 若 root.left 有左或右子树 则 返回的depth 为 root 函数执行前的depth参数
// 向root的右子树执行探索
depth = traverseMaxDepth(root.right, depth);
//root的左右子树都探索完了就 depth-- 向上回溯一层
depth--;
return depth;
}
求二叉树最大深度 不外置变量
/*计算最大深度 不引入外界变量*/
public static int maxDepth2(TreeNode root) {
if (root == null) {
return 0;
}
int left = maxDepth2(root.left) + 1;
int right = maxDepth2(root.right) + 1;
// root 节点 没有左右子树的条件下 返回 1
// 否则返回 左右子树的最大高度+1
return Math.max(left, right);
}
二叉树求前序遍历结果
/*前序遍历 递归方法1 */
public static void PreOrderTraverse(TreeNode root) {
if (root != null) {
linkedListPreOrder.add(root.val);
PreOrderTraverse(root.left);
PreOrderTraverse(root.right);
} else {
return;
}
}
二叉树求 每个节点所在层数与每个节点的左右子树上的节点总数
/*如何打印出每个节点的左右子树各有多少节点*/
public static int traverseRootCount(TreeNode root) {
if (root == null) {
return 0;
}
int leftCount = traverseRootCount(root.left);
int rightCount = traverseRootCount(root.right);
System.out.printf("当前节点为%d, 它的左子树有%d个节点, 右子树有%d个节点\n", root.val, leftCount, rightCount);
return leftCount + rightCount + 1;
}
/*如何打印出每个节点的左右子树各有多少节点 与所在层次 */
public static int traverseRootCount(TreeNode root, int level) {
if (root == null) {
return 0;
}
level++;
int leftCount = traverseRootCount(root.left, level);
int rightCount = traverseRootCount(root.right, level);
System.out.printf("当前节点为%d, 位于第%d层, 它的左子树有%d个节点, 右子树有%d个节点\n",
root.val, level, leftCount, rightCount);
return leftCount + rightCount + 1;//返回节点个数
}
力扣 543 二叉树的直径
二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 root 。两节点之间路径的 长度 由它们之间边数表示。
int max = 0;
public int diameterOfBinaryTree(TreeNode root) {
// 二叉树最长直径 即 二叉树 左右子树最长深度之和
// 对所有节点都求一次直径!!!!
if(root==null){
return 0;
}
int leftMax = depthMax(root.left);
int rightMax = depthMax(root.right);
max = Math.max(max,leftMax+rightMax);
return max;
}
public int depthMax(TreeNode root){
if(root == null){
return 0;
}
int left = depthMax(root.left) + 1;
int right = depthMax(root.right) + 1;
max = Math.max(max,left-1+right-1);
// 更新最大直径的值 直到最后一次递归最外层函数时 计算 以最初的root为根的最大直径
return Math.max(left,right);
}