【问题标题】:Remove duplicates from generic list<T>从通用列表中删除重复项<T>
【发布时间】:2010-04-07 17:44:22
【问题描述】:

我提供了从 .NET 2.0 中的通用列表 中删除重复项的解决方案,如下所示:

List<CaseStudy> caseStudies = CaseStudyDAO.FindCaseStudiesByDate(DateTime.Now.Date, DateTime.Now.Date.AddDays(1));
caseStudies.RemoveAll(
        delegate(CaseStudy c)
        {
            return caseStudies.IndexOf(c) != caseStudies.FindIndex(
                delegate(CaseStudy f) { return c.Str == f.Str; });
        });

我的问题是:

有没有更有效的方法来做到这一点?仅 .NET 2.0 解决方案
上述解决方案的复杂性是什么?

谢谢,
jan2k10

【问题讨论】:

  • 问题是关于具体的解决方案
  • sry,该问题的答案包含复杂性和最有效的方式 - 几乎所有您要求的东西......您可能应该重申您的问题,只询问您的解决方案的复杂性

标签: c# generics .net-2.0 duplicate-data


【解决方案1】:

RemoveAll 的时间复杂度是 O(n)。索引的时间复杂度是 O(n),所以这是 O(n^2) 时间复杂度的总和。我认为空间复杂度是 O(1)。

有没有更有效的方法来做到这一点?是的。只要你愿意花更多的空间,你可以在 O(n) 时间复杂度内完成它。

【讨论】:

  • 加上解释复杂性
  • 是的,RemoveAll的空间复杂度是O(1)。正如 Eric 建议的那样,如果您愿意使用更多空间,您可以构建列表中项目的Dictionary&lt;T&gt;(将项目用作键和值,或类似的东西)。或者寻找人们已经构建的预先存在的Set&lt;T&gt; 实现。
【解决方案2】:

只是为了扩展 Eric 关于 O(n) 时间的评论,如果您愿意使用更多空间,我会这样做:

Dictionary<string, CaseStudy> lookup = new Dictionary<string, CaseStudy>();
foreach (CaseStudy cs in caseStudies)
{
    lookup[cs.Str] = cs;
}
caseStudies = new List<CaseStudy>(lookup.Values);

几点说明:

  • 这会更改caseStudies 的值以引用新列表。如果您希望它在同一个 List&lt;T&gt; 内,您可以使用:

    caseStudies.Clear();
    caseStudies.AddRange(lookup.Values);
    
  • 这会使列表中的 last 元素与每个不同的 Str 值保持一致。那只是为了让它尽可能短。如果您想要 first 元素,请使用:

    foreach (CaseStudy cs in caseStudies)
    {
        if (!lookup.ContainsKey(cs.Str))
        {
            lookup[cs.Str] = cs;
        }
    }
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-20
    • 2014-09-30
    • 2011-01-13
    • 2021-04-02
    • 2016-01-28
    相关资源
    最近更新 更多