Leetcode C++《热题 Hot 100-19》543.二叉树的直径

Leetcode C++《热题 Hot 100-19》543.二叉树的直径

  1. 题目
    给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过根结点。

示例 :
给定二叉树

      1
     / \
    2   3
   / \     
  4   5    

返回 3, 它的长度是路径 [4,2,1,3] 或者 [5,2,1,3]。

注意:两结点之间的路径长度是以它们之间边的数目表示。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/diameter-of-binary-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

  1. 思路
  • 方案1(88ms,35.9MB):这棵树任意两个之间之间路径长度的最大值,这个也可以用递归大法做的
    • 递归大法就是max(最长直径包含root,不包含root的左子树, 不包含root的右子树)
    • 包含root的最长直径计算要看根节点要叶子节点的最长距离【编程之美是有这个题目的】
    • 时间复杂度是n*height
    • 空间复杂度:递归里面套递归,height*height
  • 方案2:DFS遍历,时间复杂度和空间复杂度都是n
    • 其实最长路径最后肯定经过了某一个节点。在更新root节点路径最长节点数的时候,顺便就计算了该节点的最长路径节点数目,更新max路径节点数,最后dfs整颗树,max路径节点数也得到了,减去1即为答案。
  • 为什么要用路径节点数,而不用路径段数,因为路径节点数更好表示,程序更好实现。比如用路径段数,更新res,需要判断左孩子有没有,右孩子有没有,段数应该增加几;空节点路径段数怎么表示,没有孩子的路径段数怎么表示,这些都会影响dfs的结果。用路径段数代码不够简洁,可以直观对比方案1(路径段数)和方案2(路径节点)的实现
  1. 代码
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
/*
    int diameterOfBinaryTree(TreeNode* root) {
        //方案1(88ms,35.9MB):这棵树任意两个之间之间路径长度的最大值,这个也可以用递归大法做的
        if (root == NULL)
            return 0;
        if (root->left == NULL && root->right == NULL)
            return 0;
        int add;
        if (root->left != NULL && root->right != NULL)
            add = 2;
        else
            add = 1;
        int leftres = diameterOfBinaryTree(root->left);
        int rightres = diameterOfBinaryTree(root->right);
        int includeRootRes = add + longStepToLeaf(root->left) + longStepToLeaf(root->right);
        return max(max(leftres, rightres), includeRootRes);
    }

    int longStepToLeaf(TreeNode* root) {
        if (root == NULL)
            return 0;
        if (root->left == NULL && root->right == NULL)
            return 0;
        return max(longStepToLeaf(root->left), longStepToLeaf(root->right))+1;
    }
*/    

    //采用方案2(24ms, 19.9mb),DFS遍历,时间复杂度和空间复杂度都是n
    //这个题目往深了看,可以考虑DFS,在DFS的过程中,更新res
    int res;
    int diameterOfBinaryTree(TreeNode* root) {
        res = 1;
        dfs(root);
        return res-1;  //路径长度=节点数目-1
    }

    int dfs(TreeNode* root) {
        if (root == NULL)  //计算的是节点数目
            return 0;
        int left = dfs(root->left);
        int right = dfs(root->right);
        res = max (res, left + right  + 1);  //在计算最大路径节点的过程中,顺便更新max 路径长度
        return max(left, right) + 1;  //左子树的路径节点与右子树路径节点的max值+1,就是该root的最大路径节点
    }
};

你可能感兴趣的:(刷题)