LeetCode 543. Diameter of Binary Tree 解题笔记

Posted 枯萎的海风

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 543. Diameter of Binary Tree 解题笔记相关的知识,希望对你有一定的参考价值。

1. 题目描述

https://leetcode.com/problems/diameter-of-binary-tree/#/description

Given a binary tree, you need to compute the length of the diameter of the tree. The diameter of a binary tree is the length of the longest path between any two nodes in a tree. This path may or may not pass through the root.

Example:
Given a binary tree
1
/ \\
2 3
/ \\
4 5
Return 3, which is the length of the path [4,2,1,3] or [5,2,1,3].

Note: The length of path between two nodes is represented by the number of edges between them.

2. 解题思路

这其实是一道关于二叉树的问题, 一般此类问题都是通过采用递归的思路进行处理,我们可以这样想,其实我们需要求解的所谓的D(diameter)实际上可以这么表示:

D=max(Dleft_child,Dright_child,maxDeepleft+maxDeepright)
也就是说,为了求解这个问题,我们可以将他拆解为3个部分,分别为只包含左子树的子问题 Dleft_child 和 只包含右子树的子问题 Dright_child , 以及经过当前根节点的问题

3. 代码实现

3.1 first version

通过上面给出的思路,我们可以非常容易的给出实现代码:
我们的first-version代码实际上只是简单的将问题使用递归进行处理,由于需要知道子树的深度信息,从而引入了getMaxHeight() 这个递归函数

/**
 * 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) 
        if (root == nullptr)
            return 0;
        int leftpart = 0, rightpart = 0, leftheight = 0, rightheight = 0;
        if (root->left)
            leftpart = diameterOfBinaryTree(root->left);
            leftheight = getMaxHeight(root->left);
                   
        if (root->right)
            rightpart = diameterOfBinaryTree(root->right);
            rightheight = getMaxHeight(root->right);
        

        return max(max(leftpart, rightpart), leftheight + rightheight);
    

private:
    int getMaxHeight(TreeNode * root)
        if (root == nullptr)
            return 0;
        int maxHeightLeft = 0, maxHeightRight = 0;
        if (root->left)
            maxHeightLeft = getMaxHeight(root->left);
        if (root->right)
            maxHeightRight = getMaxHeight(root->right);
        return max(maxHeightLeft, maxHeightRight) + 1;
    
;

运行效果:

3.2 second-version

考虑到我们的diameterOfBinaryTree 和 getMaxHeight所实现的特征手段都特别的相像,我们可以考虑将他们合并起来,提高代码运行效率,于是有了如下版本

/**
 * 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) 
        return getMaxHeightAndDiameter(root).first;
    

private:
    pair<int, int> getMaxHeightAndDiameter(TreeNode * root)
        if (root == nullptr)
            return pair<int, int>0, 0;
        int leftpart = 0, rightpart = 0, leftheight = 0, rightheight = 0;
        if (root->left)
            auto leftPart = getMaxHeightAndDiameter(root->left);
            leftpart = leftPart.first;
            leftheight = leftPart.second;
        
        if (root->right)
            auto rightPart = getMaxHeightAndDiameter(root->right);
            rightpart = rightPart.first;
            rightheight = rightPart.second;
        
        return pair<int, int>max(max(leftpart, rightpart), leftheight + rightheight), 
            max(leftheight, rightheight) + 1;
    
;

运行效果:

4. 参考代码

https://discuss.leetcode.com/topic/83456/java-solution-maxdepth/2
这里采用的基本思想是这样的:
实际上对于每一个节点我们都可以计算以他为根节点的diameter的长度,那么我们只需要在这个过程中,挑选得到长度最长的那个diameter就可以了
可以发现这个参考代码,思想炒鸡简单。。。

public class Solution 
    int max = 0;

    public int diameterOfBinaryTree(TreeNode root) 
        maxDepth(root);
        return max;
    

    private int maxDepth(TreeNode root) 
        if (root == null) return 0;        
        int left = maxDepth(root.left);
        int right = maxDepth(root.right);        
        max = Math.max(max, left + right);        
        return Math.max(left, right) + 1;
    

5. 一些关于二叉树的常用函数

5.1 构建二叉树

在做oj的过程中,我们经常遇到二叉树这类问题,由于手工构建一个二叉树进行测试非常费劲,于是为了偷懒,我们编写了如下函数用于自动构建二叉树:

TreeNode * createTreeByString(istringstream & iss)
    string line;
    getline(iss, line, '#');
    if (line == "!" || line == "")
        return nullptr;

    TreeNode * root = new TreeNode(stoi(line));
    root->left = createTreeByString(iss);
    root->right = createTreeByString(iss);
    return root;    

实际上这是借助了先序遍历的思想进行编写,其输入的形式如下:

    istringstream iss("1#2#4#!#!#5#!#!#3#!#!#");
    auto root = createTreeByString(iss);

5.2 中序遍历二叉树

我们同时也编写了一个中序遍历二叉树的函数,用来测试上述函数

void inorder(TreeNode * root, ostringstream & oss)
    if (root)
        inorder(root->left, oss);
        oss << root->val << " ";
        inorder(root->right, oss);
    

通过oss.str()方法可以获取得到相应的字符串表示形式
测试代码如下:

TEST(createTreeByString, createTree)
    istringstream iss("1#2#4#!#!#5#!#!#3#!#!#");
    auto root = createTreeByString(iss);
    ostringstream oss;
    inorder(root, oss);
    string inorder_result = oss.str();
    EXPECT_EQ(inorder_result, string("4 2 5 1 3 "));

以上是关于LeetCode 543. Diameter of Binary Tree 解题笔记的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode 543. Diameter of Binary Tree 解题笔记

leetcode_easy543. Diameter of Binary Tree

[leetcode-543-Diameter of Binary Tree]

Leetcode 543: Diameter of Binary Tree

leetcode 543. Diameter of Binary Tree

LeetCode 543: Diameter of Binary Tree