列表

详情


DP55. 二叉树中的最大路径和

描述

二叉树里面的路径被定义为:从该树的任意节点出发,经过父=>子或者子=>父的连接,达到任意节点的序列。
注意:
1.同一个节点在一条二叉树路径里中最多出现一次
2.一条路径至少包含一个节点,且不一定经过根节点

给定一个二叉树,请你计算它的最大路径和
例如:
给出以下的二叉树,

最优路径是:2=>1=>3,或者3=>1=>2,最大路径和=2+1+3=6

数据范围:节点数满足 ,节点上的值满足
要求:空间复杂度 ,时间复杂度

输入描述

第一行输入一个正整数 n 表示二叉树的节点数
第二行输入 n 个整数表示二叉树上第 i 个节点的值
第三行输入 n 个整数表示二叉树上第 i 个节点的父节点是第几个节点,(其中第一个节点是根节点,其父节点表示为第零个节点0)。

输出描述

输出最大路径和

示例1

输入:

3
1 2 3
0 1 1

输出:

6

示例2

输入:

5
-20 8 20 15 6
0 1 1 3 3

输出:

41

说明:

其中一条最大路径为:15=>20=>6,路径和为15+20+6=41   

示例3

输入:

2
-2 -3
0 1

输出:

-2

原站题解

C 解法, 执行用时: 2ms, 内存消耗: 340KB, 提交时间: 2022-03-12

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

int max(int a,int b){
	return a>b?a:b;
}

int main(){
	
	int mm = INT_MIN;
	int m;
	scanf("%d",&m);
	int a[m],fnode[m];
	int i,j;
	int n,cnt1,cnt2 ;
    int val=mm;
	int dp[m][3];
	for(i=0;i<m;i++){
		for(j=0;j<3;j++){
			dp[i][j]=mm;
		}
	}
	for(i=0;i<m;i++){
		scanf("%d",a+i);
		dp[i][0] = a[i];
	}
	for(i=0;i<m;i++){
		scanf("%d",fnode+i);
	}
	
	for(i=m-1;i>=0;i--){
		j=i;
		n=fnode[j];
     //   val=max(val,dp[j][0]);
        
		cnt1= max(0,dp[j][1]);
		cnt2=max(0,dp[j][2]);
		val=max(val,max(dp[j][0]+cnt1+cnt2,max(cnt1,cnt2)));
		if(n==0) break; 
		cnt1=max(cnt1,cnt2)+dp[j][0];
		if(dp[n-1][1]<0){
			dp[n-1][1]=max(0,cnt1);
		
		}else{
			dp[n-1][2]=max(0,cnt1);
		}
		
	}
	

    if(m==1){
        printf("%d",a[0]);
    }else{
        printf("%d",val);
    }
	//printf("%d",val);
	
	return 0;
}

C 解法, 执行用时: 3ms, 内存消耗: 348KB, 提交时间: 2022-05-08

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
int max(int a, int b) {
    return a > b ? a : b;
}
int main() {
    int u = INT_MIN;
    int m;
    scanf("%d", &m);
    int a[m], fnode[m];
    int i, j;
    int n, x, y;
    int v = u;
    int dp[m][3];
    for (i = 0; i < m; i++) {
        for (j = 0; j < 3; j++) {
            dp[i][j] = u;
        }
    }
    for (i = 0; i < m; i++) {
        scanf("%d", a + i);
        dp[i][0] = a[i];
    }
    for (i = 0; i < m; i++) {
        scanf("%d", fnode + i);
    }
    for (i = m - 1; i >= 0; i--) {
        j = i;
        n = fnode[j];
        x = max(0, dp[j][1]);
        y = max(0, dp[j][2]);
        v = max(v, max(dp[j][0] + x + y, max(x, y)));
        if (n == 0) break;
        x = max(x, y) + dp[j][0];
        if (dp[n - 1][1] < 0) {
            dp[n - 1][1] = max(0, x);
        } else {
            dp[n - 1][2] = max(0, x);
        }
    }
    if (m == 1) {
        printf("%d", a[0]);
    } else {
        printf("%d", v);
    }
    return 0;
}

C++ 解法, 执行用时: 3ms, 内存消耗: 404KB, 提交时间: 2022-08-06

#include<stdio.h>
#include<stdlib.h>
#include<limits.h>
int max(int a,int b)
{
    return a>b?a:b;
}
int main(){
    int mm=INT_MIN;
    int m;
    scanf("%d",&m);
    int a[m],fnode[m];
    int i,j;
    int n,cnt1,cnt2;
    int val=mm;
    int dp[m][3];
    for(i=0;i<m;i++)
    {
        for(j=0;j<3;j++)
        {
            dp[i][j]=mm;
        }
    }
    for(i=0;i<m;i++)
    {
        scanf("%d",a+i);
        dp[i][0]=a[i];
    }
    for(i=0;i<m;i++)
    {
        scanf("%d",fnode+i);
    }
    for(i=m-1;i>=0;i--)
    {
        j=i;
        n=fnode[j];
        cnt1=max(0,dp[j][1]);
        cnt2=max(0,dp[j][2]);
        val=max(val,max(dp[j][0]+cnt1+cnt2,max(cnt1,cnt2)));
        if(n==0) break;
        cnt1=max(cnt1,cnt2)+dp[j][0];
        if(dp[n-1][1]<0)
        {
            dp[n-1][1]=max(0,cnt1);
        }else{
            dp[n-1][2]=max(0,cnt1);
        }
    }
    if(m==1)
    {
        printf("%d",a[0]);
    }else{
        printf("%d",val);
    }
    return 0;
}

C++ 解法, 执行用时: 3ms, 内存消耗: 412KB, 提交时间: 2022-05-08

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
int max(int a, int b) {
    return a > b ? a : b;
}
int main() {
    int u = INT_MIN;
    int m;
    scanf("%d", &m);
    int a[m], fnode[m];
    int i, j;
    int n, x, y;
    int v = u;
    int dp[m][3];
    for (i = 0; i < m; i++) {
        for (j = 0; j < 3; j++) {
            dp[i][j] = u;
        }
    }
    for (i = 0; i < m; i++) {
        scanf("%d", a + i);
        dp[i][0] = a[i];
    }
    for (i = 0; i < m; i++) {
        scanf("%d", fnode + i);
    }
    for (i = m - 1; i >= 0; i--) {
        j = i;
        n = fnode[j];
        x = max(0, dp[j][1]);
        y = max(0, dp[j][2]);
        v = max(v, max(dp[j][0] + x + y, max(x, y)));
        if (n == 0) break;
        x = max(x, y) + dp[j][0];
        if (dp[n - 1][1] < 0) {
            dp[n - 1][1] = max(0, x);
        } else {
            dp[n - 1][2] = max(0, x);
        }
    }
    if (m == 1) {
        printf("%d", a[0]);
    } else {
        printf("%d", v);
    }
    return 0;
}

C++ 解法, 执行用时: 3ms, 内存消耗: 432KB, 提交时间: 2022-03-06

#include<bits/stdc++.h>
using namespace std;
struct Node{
    int val;
    Node* left;
    Node* right;
    Node(int _v):val(_v),left(nullptr),right(nullptr){}
};
int res = INT_MIN;
int fun(Node* root){
    if(!root) return 0;
    int left = max(fun(root -> left),0);
    int right = max(fun(root -> right),0);
    res = max(res,left + right + root -> val);
    return max(root -> val + left,root -> val + right);
    
}
int main(){
    int n ;
    cin >> n;
    int value;
    vector<Node*> node;
    for( int i = 0; i < n; i++){
        
        cin >> value;
        auto temp = new Node(value);
        node.push_back(temp);
    }
    Node* root;
    for( int i = 0; i < n; i++){
        cin >> value;
        if(value == 0){
            root = node[i];
            continue;
        }
        if(! node[value - 1] -> left){
            node[value - 1] -> left = node[i];
        }else{
            node[value - 1] -> right = node[i];
        }
    }
    fun(root);
    cout<<  res;
    return 0;
    
}

上一题