二叉树直径
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: 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)
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 ")); }
原文地址:
https://blog.csdn.net/zhyh1435589631/article/details/65939602