【C++二叉树节点间的最大距离问题】
要点:
学习树形dp套路:分析可能性–>左子树、右子树、整棵树的角度考虑
用递归先要左树信息和右数信息,然后再根据这些信息更新当前结点的信息
TIPS:
1.一定要注意递归时辅助变量的更新问题,此处qu不带引用会使初始化二叉树出错。
2.当前最大距离等于左树最大距离、右树最大距离、左右树高度和加一
代码:
参靠左神代码编写
#include <iostream>
#include <queue>
using namespace std;
struct Node //二叉树结点
{
int value;
Node *left;
Node *right;
Node() : value(0), left(nullptr), right(nullptr) {}
Node(int a) : value(a), left(nullptr), right(nullptr) {}
Node(int a, Node *left, Node *right) : value(a), left(left), right(right) {}
};
struct ReturnType //自定义返回类型(返回子树最大距离和树高)
{
int maxlen; //最大距离
int height; //树高
ReturnType() : maxlen(0), height(0) {}
ReturnType(int a, int b) : maxlen(a), height(b) {}
};
ReturnType process(Node *head)
{
if (head == nullptr)
{
return ReturnType(0, 0);
}
ReturnType left_ret = process(head->left); //向左数要信息
ReturnType right_ret = process(head->right); //向右数要信息
int pre_height = max(left_ret.height, right_ret.height) + 1; //计算当前结点信息
int pre_maxlen = max(max(left_ret.maxlen, right_ret.maxlen), left_ret.height + right_ret.height + 1);
return ReturnType(pre_maxlen, pre_height);
}
//先序遍历创建二叉树
Node *Initial_Tree(queue<int> &qu) // qu一定要带引用!!!!!!!!
{
int data = qu.front();
qu.pop();
if (data == -1)
{
return nullptr;
}
Node *head = new Node(data);
head->left = Initial_Tree(qu);
head->right = Initial_Tree(qu);
return head;
}
/* 先序遍历
void show(Node *head)
{
if (head == nullptr)
{
return;
}
cout << head->value << " ";
show(head->left);
show(head->right);
}
*/
int main()
{
/* 1
/ \
2 3
/ / \
4 5 6
\ /
7 8
*/
int arr[] = {1, 2, 4, -1, 7, -1, -1, -1, 3, 5, 8, -1, -1, -1, 6, -1, -1};
queue<int> qu;
for (int a : arr)
{
qu.push(a);
}
Node *head = Initial_Tree(qu);
ReturnType ret = process(head);
cout << "最大距离为:" << ret.maxlen << endl;
// show(head);
return 0;
}
类似题目:
员工和老板不能一起参加party,每个人有一个快乐值,求怎么安排人员有最大快乐值
最大快乐值代码:
#include <iostream>
#include <list>
using namespace std;
struct Employee
{
int happy;
list<Employee> subpeo;
Employee() : happy(0) {}
Employee(int a) : happy(a) {}
Employee(int a, list<Employee> b) : happy(a), subpeo(b) {}
};
struct ReturnData //返回类型
{
int qu_max;
int bu_max;
ReturnData() {}
ReturnData(int a, int b) : qu_max(a), bu_max(b) {}
};
ReturnData procrss(Employee x)
{
if (x.subpeo.empty())
{
return ReturnData(x.happy, 0);
}
int qu = x.happy; // x去
int bu = 0; // x不去
for (Employee empl : x.subpeo) //遍历每个子结点
{
ReturnData sub_data = procrss(empl); //取每个子节点的信息
qu += sub_data.bu_max; //更新当前结点的信息(x去时的最大值 : 所有子结点不去的最大值的和)
bu += max(sub_data.qu_max, sub_data.qu_max); // x不去时的最大值: 所有子节点去和不去时的最大值的和
}
return ReturnData(qu, bu);
}
int main()
{
/* A(4)
/ | \
B(2) I(30) C(6)
/ | \ / \
D(4) E(7) F(10) G(5) H(2) */
//初始化tree
Employee D(4);
Employee E(7);
Employee F(10);
Employee G(5);
Employee H(2);
Employee I(30);
list<Employee> B_sub = {D, E, F};
Employee B(2, B_sub);
list<Employee> C_sub = {G, H};
Employee C(6, C_sub);
list<Employee> A_sub = {B, C, I};
Employee A(4, A_sub);
ReturnData dat = procrss(A);
int result = max(dat.bu_max, dat.qu_max);
cout << "最大快乐值为:" << result << endl;
return 0;
}