|
|
/*
问题描述: 题目描述: 二叉树中的 路径 被定义为一条节点序列,序列中每对相邻节点之间都存在一条边。同一个节点在一条路径序列中 至多出现一次。该路径 至少包含一个节点,目不一定经过根节点。路径和 是路径中各节点值的总和,以先序遍历给定一个二叉树的根节点root,返回其最大路径和。 输入描述: 输入:[1,2,3,4,5] 输出:11 */ #include <bits/stdc++.h>
using namespace std;
#define emp -1
int maxSum = 0; struct Node{ int value; Node* left; Node* right; };
Node* createNode(){ Node* root = new Node(); root->left = nullptr; root->right = nullptr; return root; }
void createFullBT_DFS(Node *&root, vector<int> &numbers, int len, int i) { if(i <= len) { root->value = numbers[i - 1]; if(2 * i <= len && numbers[2 * i - 1] != emp) { root->left = createNode(); createFullBT_DFS(root->left, numbers, len, 2 * i); } if((2 * i + 1) <= len && numbers[2 * i] != emp) { root->right = createNode(); createFullBT_DFS(root->right, numbers, len, 2 * i + 1); } } }
int maxGain(Node* node) { if (node == nullptr) { return 0; } // 递归计算左右子节点的最大贡献值
// 只有在最大贡献值大于 0 时,才会选取对应子节点
int leftGain = max(maxGain(node->left), 0); int rightGain = max(maxGain(node->right), 0); // 节点的最大路径和取决于该节点的值与该节点的左右子节点的最大贡献值
int priceNewpath = node->value + leftGain + rightGain; // 更新答案
maxSum = max(maxSum, priceNewpath); // 返回节点的最大贡献值
return node->value + max(leftGain, rightGain); }
void preOrder(Node *root) { if(root != NULL) { cout << root->value << " "; preOrder(root->left); preOrder(root->right); } }
int main(){ string str = "[1,2,3,4,5]"; string str_update = str.substr(1, str.length()-2); char* str_input = (char*)str_update.c_str(); vector<int> nums; int val = 0; while(*str_input != '\0'){ if(*str_input != ','){ val = val * 10 + (*str_input - '0'); } else{ nums.push_back(val); val = 0; } str_input++; } nums.push_back(val); Node* root = createNode(); createFullBT_DFS(root, nums, nums.size(), 1); // preOrder(root);
maxGain(root); cout << maxSum <<endl; return 0; }
|