题目:
来自牛客网 :
二叉树里面的路径被定义为:从该树的任意节点出发,经过父=>子或者子=>父的连接,达到任意节点的序列。
注意:
1.同一个节点在一条二叉树路径里中最多出现一次
2.一条路径至少包含一个节点,且不一定经过根节点
给定一个二叉树的根节点root,请你计算它的最大路径和。
例如:
给出以下的二叉树,
最优路径是:2=>1=>3,或者3=>1=>2,最大路径和=2+1+3=6
数据范围:节点数满足 0≤n≤10000 ,节点上的值满足 |val|≤1000
输入格式:
输入为一组用空格间隔的整数,表示二叉树的层次序列。0表示空结点。
输出格式:
输出最大路径和。
输入样例1:
-20 8 20 0 0 15 6
输出样例1:
41
输入样例2:
-2 0 -3
输出样例2:
-2
思路分析:
首先,要先学会怎么存这个二叉树,由于题目给的数字是若干个,那么我们用数组来存这个二叉树,那么按顺序存会有性质,root*2会到左子树,root*2+1会到右子树,由此可以搜索整个二叉树。
接着,按着这个性质,搜索左右子树,递归到最底层,归的过程中更新最大值。
注意:要将空节点初始化为无穷小,递归过程中用0来对于负数的左右子树直接不考虑。
代码:
#include<iostream>
#include<cmath>
#include<map>
#define endl '\n'
using namespace std;
int maxn = -2e9,a[10005],cnt=0;
int dfs(int root)
{
int left,right; //找 左右子树最大 或者 左右子树和根最大
if (root > cnt) return 0;
left = max(0,dfs(root*2)); //左
right = max(0,dfs(root*2+1)); //右
maxn = max(maxn,left+right+a[root]); //更新最大值
return max(left,right)+a[root];
}
int main()
{
int x;
while(~scanf("%d",&x)) //数组存二叉树
{
cnt++;
if (x == 0) x = -2e9;
a[cnt] = x;
}
dfs(1);
cout<<maxn;
return 0;
}