以最有效的方式列出操作

时间:2012-02-29 21:45:54

标签: algorithm

我需要对列表的内容执行一些操作。 List保存边缘的权重,另一个边缘显示这些边缘出现在图表中。

我想要做的是不对我的列表进行重组,确保对于列表中的每个x值,列表中剩余值的总和大于x。如果不是这种情况,则需要从列表中删除x。

例如假设我的列表包含数字3 4 5 23 3 31 10 100 3 5

由于(3 + 4 + 5 + 23 + 3 + 31 + 10 + 5)小于100,因此需要从列表中删除100。

到目前为止,我能够提出的是

static double calculatesum(List<Edge> e)
        {
            double total = e.Sum(item => item.segmentlength);
            //what I want to check each and then delete when I hit one I need to deactivate
            foreach (Edge edge in e)
            {
                if (1 > (total - edge.segmentlength))
                {
                    edge.isactive = false;
                    total -= edge.segmentlength;
                }
            }

            return 0;
        } 

如何以更有效的方式实现这一目标?

2 个答案:

答案 0 :(得分:0)

这取决于你最有效的意思。

如果您正在寻找最佳渐近复杂度,那么请进行排序(并记住每个元素的位置)。由于列表中有简单的数字,或许权重有限,您可能比O(n*log n)做得更好。然后简单地计算一个总和,然后重复减去最后一个元素,将其与总和进行比较,并在必要时将其删除直到你完成。

如果通常只需要删除几个元素,那么只需在总和中搜索最大元素并重复此过程,直到没有要删除的元素为止。

答案 1 :(得分:0)

要使其成为O(n),请执行以下操作:

1. create sum of all elements 
2. for each element
2a. substract element from sum
2b. check new sum against element
2ba if to remove remember element
2bb else add element to sum
3. remove remembered elements

直到这里它将是O(n)

我忘了考虑多次运行,直到没有元素被删除。因此,在预先判断的情况下,最糟糕的情况是未洗牌的O(n ^ 2)和O(n + n log n)。