简体   繁体   English

在二进制搜索树中查找最小和的算法改进

[英]Algorithmic improvement for finding minimum sum in a Binary Search Tree

I wrote the following function to find out the minimum sum of any path in a Binary Search Tree: 我写了以下函数来找出二进制搜索树中任何路径的最小总和:

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;
}

While the above code generates the correct output, I feel that I am not leveraging the fact that it is a Binary Search Tree (BST) and not just a Binary Tree. 虽然上面的代码生成了正确的输出,但我觉得我没有利用它是二进制搜索树(BST)而不仅仅是二叉树的事实。

In a BST the left child node is smaller than the root and right node, so logically we can only consider the left child nodes of each root; 在BST中,左子节点小于根节点和右节点,因此从逻辑上讲,我们只能考虑每个根节点的左子节点; but what if the BST has only a single child on the right (with say value 10) and multiple child nodes on the left (with sum >10)? 但是,如果BST右边只有一个孩子(比如10),左边有多个子节点(总和> 10)怎么办?

In this case the minimum sum would be 10 (which is on the right). 在这种情况下,最小总和将是10(在右侧)。

How I would be able to leverage the BST property, if at all? 如果可以的话,我将如何利用BST属性? Also, any other optimizations that I can use in my approach? 还有,我可以在我的方法中使用的任何其他优化?

Note: Edited the code to resolve the error; 注意:编辑代码以解决错误;

An informed search could help in some cases. 在某些情况下,知情搜索可能有所帮助。
In the worst case, the computational cost is exactly the same of your algorithm. 在最坏的情况下,计算成本与您的算法完全相同。

As an example: 举个例子:

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;
}

The basic idea is to track the current minimum while performing a DFS. 基本思想是在执行DFS时跟踪当前最小值。 This will give you the chance to prune entire subtrees whenever the sum of the values to their root are already greater than the current minimum. 只要其根值的总和已经大于当前最小值,这将使您有机会修剪整个子树。
Moreover, exploring the left tree before to look at the right one could help maximizing the result (no assurance indeed, but it's a good idea because of how BSTs are defined). 此外,在探索左侧树以查看正确的树之前可以帮助最大化结果(确实没有保证,但由于如何定义BST,这是一个好主意)。

See a comparison of the two approaches on wandbox . 查看wandbox上两种方法的比较。
As you can see, the second function doesn't explore at all trees that are not promising. 正如您所看到的,第二个函数并没有探索所有不合适的树。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM