leetcode: Binary Tree Maximum Path Sum

本文探讨了如何求解二叉树中最大路径和的问题,给出了一种递归算法实现思路,通过维护一个全局变量来记录遍历过程中的最大路径值。

问题描述:

Given a binary tree, find the maximum path sum.

For this problem, a path is defined as any sequence of nodes from some starting node to any node in the tree along the parent-child connections. The path does not need to go through the root.

For example:
Given the below binary tree,

       1
      / \
     2   3

 

 

Return 6.

原问题链接:https://leetcode.com/problems/binary-tree-maximum-path-sum/

 

问题分析

  这个问题一开始比较难找到解决的思路。因为这里要求的路径并不一定是从树的根节点经过的路径。而如果把这个问题更加一般化的话,我们计算从某个节点到叶节点的所有可能最大路径,无非就是递归的计算它的两个子节点的最大路径值,再把它们的值和自身加起来。只是我们最终返回的那个是经过根节点的值,它不一定是最大的。

  在这里,突然给了我们一个想法,就是在前面递归的过程中,每次都要比较和计算一个当前节点的最大路径值。而如果在这个时候我们用一个全局的变量保存这个最大值,每次都和这个值比较调整的话,这个问题就可以解决了。

  于是我们有如下的代码:

 

/**
 * Definition for binary tree
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    int maxValue;
    
    public int maxPathSum(TreeNode root) {
        maxValue = Integer.MIN_VALUE;
        maxPathDown(root);
        return maxValue;
    }
    
    private int maxPathDown(TreeNode node) {
        if(node == null) return 0;
        int left = Math.max(0, maxPathDown(node.left));
        int right = Math.max(0, maxPathDown(node.right));
        maxValue = Math.max(maxValue, left + right + node.val);
        return Math.max(left, right) + node.val;
    }
}

  从实现的思路来说,这里通过借求经过根节点的所有路径的最大值,在每次递归的过程中比较计算最长的路径。这种方式比较巧妙。 

### 使用 Parent 链构建三叉链表 为了实现 `BinaryTree<String>` 的 `createByGenlist` 方法,该方法基于给定的广义表字符串来创建一棵二叉树。此过程涉及解析输入字符串并利用 parent 链建立节点之间的父子关系。 #### 解析广义表字符串 广义表是一种可以嵌套列表的数据结构形式,在这里作为描述二叉树的一种方式。每个字符代表一个结点;一对圆括号内的内容则表示子树。例如,“A(B,C(D,E))”,其中 A 是根节点,B 和 C 是其孩子节点,D 和 E 则分别是 C 的两个孩子节点。 #### 创建节点及其关联 对于每一个新读取到的字母(即非空格和括号之外的部分),都会创建一个新的 `TreeNode` 实例,并将其添加至当前正在处理中的父级节点之下。如果遇到左括号,则意味着即将进入下一层级的孩子节点序列;而当碰到右括号时,则返回至上一层次继续处理剩余部分[^1]。 ```cpp #include <iostream> #include <stack> using namespace std; struct TreeNode { string data; int parentIndex = -1; // 记录父节点索引,默认为-1表示无父节点 }; class BinaryTree { public: vector<TreeNode*> nodes; BinaryTree(const string& genListStr) : index(-1), currentParent(nullptr){ parseGenList(genListStr); } private: stack<int> parentsStack; int index; TreeNode* currentParent; void addNode(char ch) { auto newNode = new TreeNode{string(1, ch)}; if (!parentsStack.empty()) { newNode->parentIndex = parentsStack.top(); } nodes.push_back(newNode); ++index; if (currentParent != nullptr && currentParent->data.back() == '(') { parentsStack.push(index); } } void parseGenList(const string& str) { for (char c : str) { switch(c) { case '(': break; case ')': if(!parentsStack.empty()) parentsStack.pop(); break; default: addNode(c); break; } } } }; ``` 上述代码片段展示了如何通过遍历广义表达式的每一项来进行相应的操作:每当发现新的元素就调用 `addNode()` 函数增加相应的新节点;而在遇见左右括号的时候调整栈顶指针的位置以反映层级变化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值