1. 题目
2. 解题思路
使用深度优先搜索,在回退时记录当前结点左右子树深度之和作为可能的最大直径,
并计算以当前结点为根节点的树的深度,为父结点计算提供数据
计算所有结点的左右子树深度,其和最大的即为最大直径
3. 代码
/**
* 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) {
int ans = 0;
stack<TreeNode*> st; // 记录搜索路径
map<TreeNode*, int> length; // 记录各结点为根节点的树的深度
if(root != 0){
st.push(root);
bool chr = false; // 是否从右孩子返回
bool chl = false; // 是否从左孩子返回
while(st.size() != 0){
TreeNode *node = st.top();
// cout<<node->val<<endl;
if(node->left == 0 && node->right == 0){ // 是否为叶子结点
length[node->left] = 0;
length[node->right] = 0;
// cout<<node->val<<endl;
}else if(!chr){ // 不是从右孩子返回
if(node->left != 0 && !chl){ // 左孩子不为空 且 不是从左孩子返回
st.push(node->left); // 进入左子树
}else if(node->right != 0){ // 右孩子不为空
chl = false;
st.push(node->right); // 进入右子树
}else{
chr = true; // 右孩子为空,下一轮认为是已从右孩子返回
}
continue; // 继续
}else{ // 从右孩子返回,则直接回退
chr = false;
}
st.pop(); // 进入回退流程
if(length[node->left] + length[node->right] > ans){
ans = length[node->left] + length[node->right];
} // 计算左右子树深度之和
length[node] = (length[node->left] > length[node->right] ?
length[node->left] :
length[node->right]
) + 1; // 计算当前结点为根节点的树的深度
if(st.size() == 0){ // 判空,防止空指针
break;
}
if(node == st.top()->left){
chl = true; // 当前结点是父结点的左孩子
}else{
chr = true; // 当前结点是父结点的右孩子
}
}
}
return ans;
}
};