class Solution {
private int max;
public int diameterOfBinaryTree(TreeNode root) {
helper(root);
return max;
}
private int helper(TreeNode root){
if(root == null){
return 0;
}
int left = helper(root.left);
int right = helper(root.right);
// 直径等于左右子树高度和
max = Math.max(left+right,max);
return Math.max(left,right)+1;
}
}
class Solution {
int max = 0;
public int diameterOfBinaryTree(TreeNode root) {
//最长路径是左子树加上右子树的高度,但是注意不一定从根节点出发。
getHeight(root);
return max;
}
public int getHeight(TreeNode root){
if(root == null){
return 0;
}
int left = getHeight(root.left);
int right = getHeight(root.right);
//计算高度的逻辑是左右子树取最大值+1
int res = Math.max(left, right) + 1;
//计算直径的逻辑是左右子树高度相加
max = Math.max(left + right, max);
return res;
}
}
class Solution {
int max = 0;
public int diameterOfBinaryTree(TreeNode root) {
height(root);
return max;
}
private int height(TreeNode root) {
if (root == null) return 0;
int l = height(root.left);
int r = height(root.right);
max = Math.max(max, l + r);
return Math.max(l, r) + 1;
}
}
//var res int 很奇怪不能定义全局变量保存答案
func diameterOfBinaryTree(root *TreeNode) int {
var help func(root *TreeNode) int
res := 0
if root == nil{
return 0
}
help = func(root *TreeNode) int {
if root == nil {
return 0
}
left_h := help(root.Left) // 左子树最大深度
right_h := help(root.Right) //右子树最大深度
res = max(res, left_h + right_h) //每遍历一个节点 更新整个树的最大直径
return max(left_h, right_h) + 1 //返回最大子树深度 + 1
}
help(root)
return res
}
func max(a, b int) int {
if a > b{
return a
}
return b
}
class Solution {
int val = 0;
public int diameterOfBinaryTree(TreeNode root) {
depth(root);
return val;
}
int depth(TreeNode node){
if(node == null){
return 0;
}
int left = depth(node.left);
int right = depth(node.right);
val = Math.max(left+right,val);
return Math.max(left,right)+1;
}
}
//使用dfs 遍历每一个节点 以每个节点为中心点计算直径
//时间复杂度O(n)
//空间复杂度O(height)//height 为树的高度
int res;
public int diameterOfBinaryTree(TreeNode root) {
if(root==null) return 0;
dfs(root);
return res;
}
private int dfs(TreeNode node){
if(node.left==null&&node.right==null) return 0;
int left =node.left==null?0:dfs(node.left)+1;
int right =node.right==null?0:dfs(node.right)+1;
res=Math.max(res,left+right);
return Math.max(left,right);
}
class Solution {
int len = 0;
public int diameterOfBinaryTree(TreeNode root) {
depth(root);
return len;
}
public int depth(TreeNode node) {
if (node == null) {
return 0;
}
int L = depth(node.left);
int R = depth(node.right);
len = Math.max(len, L+R);
return Math.max(L, R) + 1;
}
}
int ans;
public int diameterOfBinaryTree(TreeNode root) {
ans = 1;
depth(root);
return ans - 1;
}
public int depth(TreeNode node) {
if (node == null) {
return 0;//访问到空节点,返回0
}
int L = depth(node.left);//左儿子为根的子树的深度
int R = depth(node.right);//右儿子为根的子树的深度
ans = Math.max(ans , L + R + 1);//计算d_node即L+R+1并更新ans
return Math.max(L , R) + 1;//返回该节点为根的子树的深度
}
class Solution {
int maxL;
public int diameterOfBinaryTree(TreeNode root) {
maxL = 1;
depth(root);
return maxL - 1;
}
//层次优先遍历
public int depth(TreeNode root){
if(root == null ){
return 0;
}
int L = depth(root.right);
int R = depth(root.left);
maxL = Math.max(maxL, L + R + 1);
return Math.max(L, R) + 1;
}
//1、最大直径不过头节点
//2、最大直接过头节点
// 设置函数向左右孩子要 左右孩子的最大直径 和 最大高度
//最后比较左右最大直径 左右高度之和 比较
public int diameterOfBinaryTree(TreeNode root) {
return process(root).maxDistance;
}
public static class Info{
public int maxDistance;
public int height;
public Info(int m, int h){
maxDistance = m;
height = h;
}
}
public static Info process(TreeNode root){
if(root == null){
return new Info(0, 0);
}
Info leftInfo = process(root.left);
Info rightInfo = process(root.right);
int height = Math.max(leftInfo.height, rightInfo.height) + 1;
int p1 = Math.max(leftInfo.maxDistance, rightInfo.maxDistance);
int p2 = leftInfo.height + rightInfo.height;
int maxDistance = Math.max(p1, p2);
return new Info(maxDistance, height);
}
class Solution {
int num;
public int diameterOfBinaryTree(TreeNode root) {
//深度计算
Depth(root);
return num;
}
int Depth(TreeNode root) {
if (root == null) {
return 0;
}
int L = Depth(root.left);
int R = Depth(root.right);
num = Math.max(num, L + R);
return Math.max(L, R) + 1;
}
}
class Solution {
int ans = 0;
public:
int diameterOfBinaryTree(TreeNode* root) {
if (root == nullptr)
return 0;
findHeight(root);
return ans;
}
int findHeight(TreeNode *root)
{
if (root == nullptr)
return 0;
int leftHeight = findHeight(root->left);
int rightHeight = findHeight(root->right);
int ret = std::max(leftHeight, rightHeight) + 1;
ans = std::max(leftHeight + rightHeight, ans);
return ret;
}
};
class Solution {
int ans;
public int diameterOfBinaryTree(TreeNode root) {
ans = 0;
depth(root);
return ans ;
}
public int depth(TreeNode node) {
if (node == null) {
return 0;
}
int L = depth(node.left);
int R = depth(node.right);
ans = Math.max(ans, L+R);
return Math.max(L, R) + 1;
}
}
// 左节点高度 + 右节点高度 + 1
var diameterOfBinaryTree = function(root) {
let result = -Infinity;
const depth = function(root) {
if(!root) {
return 0;
}
let left = depth(root.left);
let right = depth(root.right)
// 更新全局变量
result = Math.max(result, left + right + 1)
return Math.max(left,right) + 1;
}
depth(root);
return result - 1;
};
/**
比较暴力的方法,前序遍历,将当前节点的左右子树高度加一下,取最大值就好
缺点是比较慢
时间复杂度O(n^2)
空间复杂度O(n)
*/
class Solution {
public int diameterOfBinaryTree(TreeNode root) {
TreeNode p = root;
Deque<TreeNode> stack = new ArrayDeque<>();
int ans = 0;
while(p!=null || !stack.isEmpty()){
if(p!=null){
stack.push(p);
ans = Math.max(ans, function(p.left)+function(p.right));
p = p.left;
}
else{
p = stack.pop();
p = p.right;
}
}
return ans;
}
public int function(TreeNode root){
if(root == null) return 0;
return Math.max(function(root.left), function(root.right)) + 1;
}
}
/**
看了题解真是简洁,直接在递归深度的时候就计算直径,不用先计算深度,直接降了下来,我好笨
时间复杂度O(n)
空间复杂度O(n)
*/
class Solution {
int ans;
public int diameterOfBinaryTree(TreeNode root) {
ans = 0;
function(root);
return ans;
}
public int function(TreeNode root){
if(root == null) return 0;
int l = function(root.left);
int r = function(root.right);
ans = Math.max(ans, l+r);
return Math.max(l, r) + 1;
}
}
class Solution {
int res = 1;
public int diameterOfBinaryTree(TreeNode root) {
if(root == null) return 0;
f(root);
return res-1;
}
private int f(TreeNode root){
if(root == null) return 0;
int left = f(root.left);
int right = f(root.right);
res = Math.max(res,left+right+1);
return Math.max(left,right)+1;
}
}
class Solution {
int ans;
int depth(TreeNode* root){
if(root == nullptr) return 0;
int l = depth(root->left);
int r = depth(root->right);
ans = max(ans, l + r + 1);
return max(l, r) + 1;
}
public:
int diameterOfBinaryTree(TreeNode* root) {
ans = 1;
depth(root);
return ans - 1;
}
};
class Solution {
int max;
public int diameterOfBinaryTree(TreeNode root) {
depth(root);
return max;
}
private int depth(TreeNode root) {
if(root == null) {
return 0;
}
int L = depth(root.left);//不能在这两层加一
int R = depth(root.right);
max = Math.max(max, L+R);
return Math.max(L, R)+1;//要在这里加一
}
}
class Solution {
int ans = 0;
public int diameterOfBinaryTree(TreeNode root) {
if(root == null) return ans;
rec(root);
return ans - 1;
}
public int rec(TreeNode node) {
if(node == null) return 0;
int L = rec(node.left);
int R = rec(node.right);
int num_node = L + R + 1;
if(num_node > ans)
ans = num_node;
return Math.max(L, R) + 1;
}
}
class Solution {
int max = Integer.MIN_VALUE;
public int maxPathSum(TreeNode root) {
if(root == null) return 0;
dfs(root);
return max;
}
public int dfs(TreeNode root){
if(root == null) return 0;
int left = Math.max(0, dfs(root.left));
int right = Math.max(0,dfs(root.right));
max = Math.max(max,left+right+root.val);//当前路径总和
return Math.max(left,right) + root.val;
}
}
class Solution {
int res = 0;
public int diameterOfBinaryTree(TreeNode root) {
maxDepth(root);
return res;
}
public int maxDepth(TreeNode root){
if(root == null){
return 0;
}
int leftMax = maxDepth(root.left);
int rightMax = maxDepth(root.right);
res = Math.max(res,leftMax + rightMax);
return 1 + Math.max(leftMax,rightMax);
}
}
共以下 33 个回答
遍历过程中更新最大值
求高度 顺便更新一下最大值
时间O(n) 空间O(height)
时间复杂度:O(n)
空间复杂度:O(height),递归深度(栈空间)
解题思路:二叉树的直径等于左子节点和右子节点的深度之和加一,递归遍历所有节点,找到最大直径节点;
时间复杂度:O(n)
空间复杂度:O(height),递归深度(栈空间)
时间 O(n)
空间 O(height) 如果计算递归栈的空间 不计算栈的空间 应该是 O(1)
思路:这题要找二叉树以每一个节点为起点的最长路径,路径的长度就是以这条路径中的根节点的左右子树的深度之和。写一个求root节点深度的函数,函数中更新res就行。时间复杂度为O(N),空间复杂度为O(height)。
时间空间复杂度都是O(N)
思路:深度优先搜索,然后回溯的时候记录每一个根节点的最大路径
时间复杂度:O(N),其中N为二叉树的节点数
空间复杂度:O(Height),其中 Height为二叉树的高度
时间复杂度:O(n)
空间复杂度:O(n)
解题思路:该题是求出直径,也就是说一个路径下一定会有最近的父公共节点,那么路径长度=左子树深度+右子树深度。这里还有一点就是可以任意左右子树先遍历,可以采用深度优先搜索的方式。
时间复杂度:O(N)递归求深度,每个节点只访问一次
空间复杂度:树的高度,
//一个值得注意的点是未必要经过根节点
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int res;
int fun(TreeNode root){
if(! root) return 0;
int l=fun(root->left);
int r=fun(root->right);
res=max(res,l+r);
return 1+max(l,r);
};
1、求每个子树作为根的最大路径
2、时间O(n),空间O(n)
想到了用递归求深度,但是在100/104就过不去了,还是整体思路有问题,递归!!!
时间空间复杂度O(n)
时间空间复杂度O(n)
递归,我觉得一定要从宏观语境去把握递归!!!
分析
思路和算树最大高度的那题类似,最大值一定是在二叉树的左右子树高度的和,每次递归将左右子树长度相加与最大值比较并记录,返回左右子树中最大的,时间复杂度为O(n),空间复杂度为O(lgn).
代码
递归
时间O(n)
空间O(n)
先通过深度优先搜索求出左右子树的最大深度,然后得到路径经过的节点数
树的深度变种,后续遍历
最长路径,等效于路径经过节点最大值 – 1。通过深度优先搜索可求。
543. 二叉树的直径(11.3)
时间复杂度O(N) 空间复杂度O(N)系统栈最坏情况
雷同题目
124. 二叉树中的最大路径和(11.3)
时间复杂度O(N) 空间复杂度O(N)系统栈最坏情况
相比较于上一题,此处路径要求的是最大和,改变在处理左右子树值的时候,不再是取路径+1,而是直接取左右路径的值加根节点来判断是否为最大
在返回该节点到左右子树中任意一个的最大值
687. 最长同值路径(11.3)
时间复杂度O(N) 空间复杂度O(N)系统栈最坏情况
区别在于,因为要判断同值。
最简单的方法就是判断当前节点和左右节点是否相等,相等则保留长度说明同值,不等则为0
时间:O(n),空间:O(height)
分别计算左右子树的最大深度,利用后序遍历的特性,相加得出最大直径。时间O(n),空间O(n)