【问题标题】:Algorithmic improvement for finding minimum sum in a Binary Search Tree在二叉搜索树中查找最小和的算法改进
【发布时间】:2017-01-22 19:43:34
【问题描述】:

我编写了以下函数来找出二叉搜索树中任何路径的最小总和:

int minSumPath(TreeNode* root) {
    if(root==NULL)
        return 0;

    int sum = root->value;
    if(root->left!=NULL && root->right!=NULL)
        sum += min(minSumPath(root->left),minSumPath(root->right));
    else
        if(root->left==NULL)
            sum += minSumPath(root->right);
        else
            sum += minSumPath(root->left);

    return sum;
}

虽然上面的代码生成了正确的输出,但我觉得我没有利用它是二叉搜索树 (BST) 而不仅仅是二叉树的事实。

在BST中,左子节点小于根节点和右节点,所以逻辑上我们只能考虑每个根节点的左子节点;但是如果 BST 在右侧只有一个子节点(比如值为 10)而左侧有多个子节点(总和 >10)怎么办?

在这种情况下,最小总和为 10(位于右侧)。

如果有的话,我将如何利用 BST 属性?另外,我可以在我的方法中使用任何其他优化吗?

注意:编辑代码以解决错误;

【问题讨论】:

  • @user3112926,虽然我完全同意您的观点,先生,但我正在寻求算法改进。
  • 我不知道为什么我看不到函数返回除零以外的任何值。
  • 作为一个不错的代码改进:由于您已经检查了root 以获取NULL,因此您可以省略其他级别的空检查,只需使用NULLs 调用minSumPath leftright.
  • 是的,但在下一个递归步骤中,root->leftroot->right 将是新的 root,它再次检查 NULL
  • 这个问题很有趣。一定有办法利用 BST 的结构。

标签: c++ algorithm performance optimization binary-search-tree


【解决方案1】:

在某些情况下,明智的搜索可能会有所帮助。
在最坏的情况下,计算成本与您的算法完全相同。

举个例子:

int minSumPathOpt(TreeNode* root) {
    if(root == nullptr) return 0;

    int sum = -1;

    std::stack<std::pair<TreeNode*, int>> todo;
    todo.push(std::make_pair(root, 0));

    while(not todo.empty()) {
        std::pair<TreeNode*, int> curr = todo.top();
        todo.pop();

        TreeNode *node = curr.first;        
        int part = curr.second + node->value;

        if(sum == -1 || part < sum) {
            if(!node->left && !node->right) {
                sum = part;
            } else  {
                if(node->right) todo.push(std::make_pair(node->right, part));
                if(node->left) todo.push(std::make_pair(node->left, part));
            }
        }
    }

    return sum;
}

基本思想是在执行 DFS 时跟踪当前最小值。这将使您有机会在其根的值总和已经大于当前最小值时修剪整个子树。
此外,先探索左侧树再查看右侧树可能有助于最大化结果(确实不能保证,但这是一个好主意,因为 BST 是如何定义的)。

wandbox 上查看这两种方法的比较。
如您所见,第二个函数根本没有探索那些没有希望的树。

【讨论】:

  • 感谢您的回答。您看到我们可以利用 BST 属性的某种方式吗?
  • @user6490375 我怀疑修剪没有希望的子树是你能做的最好的事情。 BST 不一定会最小化特定子树上的结果。您可以轻松地构造一棵在左子树上具有最短路径的树,在右子树上具有最短路径的树。这些可能会挫败任何利用较低值在左侧或类似情况这一事实的尝试。
猜你喜欢
  • 2020-11-01
  • 1970-01-01
  • 2020-09-03
  • 1970-01-01
  • 1970-01-01
  • 2017-08-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多