【问题标题】:Min Path Sum in a Binary Tree二叉树中的最小路径和
【发布时间】:2016-03-17 23:09:10
【问题描述】:

如何找到二叉树中的最小路径和,并打印路径?路径可以是从 ROOT 节点到任何 LEAF 节点。我已经编写了 C++ 代码来查找最小总和,但是在打印路径时遇到了问题。

int MinTreePathSum(TreeNode *head, vector<TreeNode> &path)
{
    if(!head)  // head is NULL
        return 0;
    else if(!(head->left) && head->right)  // only head->left is NULL
        return head->val+MinTreePathSum(head->right, path);
    else if(!(head->right) && head->left)  // only head->right is NULL
        return head->val+MinTreePathSum(head->left, path);
    else
        return head->val+min(MinTreePathSum(head->left, path), MinTreePathSum(head->right, path));  // none of left and right are NULL
}

没有使用参数列表中的path,谁能帮我打印出路径总和最小的路径?

【问题讨论】:

  • 1) 是否要更新路径? 2)您是否故意使用vector&lt;TreeNode&gt;而不是vector&lt;TreeNode*&gt;
  • 1) path 向量的初始大小=0,用于存储合格的TreeNode。 2)我认为我们可以做任何一种方式,只要路径是唯一确定的。
  • @Christophe 我刚刚意识到使用vector&lt;TreeNode *&gt;vector&lt;TreeNode&gt; 好得多。忘记我之前的回答 2)

标签: c++ algorithm recursion binary-tree


【解决方案1】:

而不是return head-&gt;val+min(MinTreePathSum(head-&gt;left, path), MinTreePathSum(head-&gt;right, path));,检查右路径或左路径中的哪一个是最小的。通过保存它们,您可以找到路径。

int MinTreePathSum(TreeNode *head, string &path)
{
    if(!head)  // head is NULL
        return 0;
    else if(!(head->left) && head->right)  // only head->left is NULL
    {   
        string p; 
        int val = head->val+MinTreePathSum(head->right, p);
        path = "R" + p;
        return val;
    }
    else if(!(head->right) && head->left)  // only head->right is NULL
    {
        string p;
        int val = head->val+MinTreePathSum(head->left, p);
        path = "L" + p;
        return val;
    }
    else
    {
        int vl,vr,val;
        string pl,pr;
        vl = MinTreePathSum(head->left, pl);
        vr = MinTreePathSum(head->right, pr);
        if ( vl < vr ){
             val = vl;
             path = "L" + pl;
        } else {
             val = vr;
             path = "R" + pr;
        }
        return head->val + val;
    }
}

【讨论】:

  • @sudomakeinstall2感谢您的回答。我也有同样的想法,问题是如何处理边界情况。你能分享更多关于你的想法的细节吗?谢谢!
  • @LiangLi 我没有测试过代码,但你应该明白了
【解决方案2】:

我认为你真的很接近......只需将当前节点添加到路径中,如果当前节点有两个孩子,则选择最短路径:

int MinTreePathSum(TreeNode *head, vector<TreeNode> &path)
{
    if(!head)  // head is NULL
        return 0;
    else if(!(head->left) && head->right) {  // only head->left is NULL
        path.push(*head);
        return head->val+MinTreePathSum(head->right, path);
    }else if(!(head->right) && head->left) { // only head->right is NULL
        path.push(*head);
        return head->val+MinTreePathSum(head->left, path);
    }else{ // two children, must choose one...
        path.push(*head);

        // get left and right paths
        pathLeft = vector<TreeNode>(); 
        pathRight = vector<TreeNode>();
        int valLeft = MinTreePathSum(head->left, pathLeft);
        int valRight = MinTreePathSum(head->right, pathRight);

        // actually copy the shortest path
        if (valLeft < valRight) {
            for(int i = 0; i < pathLeft.size(); ++i) {
                path.push(pathLeft[i]);
            }
        }else{
            for(int i = 0; i < pathRight.size(); ++i) {
                path.push(pathRight[i]);
            }
        }  
        // finally return the minimum path, which is the one we put in "path" already
        return head->val + min(valLeft, valRight);
    }
}

【讨论】:

  • 你可以使用copy和insert_iterator代替last for,但我不知道你是否已经学会了...
  • 这个时间复杂度是多少?
猜你喜欢
  • 2018-08-10
  • 1970-01-01
  • 2020-11-29
  • 2021-07-24
  • 2016-09-07
  • 1970-01-01
  • 2017-08-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多