有没有最便宜的方法来比较ICollection与自身。
这是我的代码:
public IEnumerable<Pet> speciesChecker()
{
foreach (Pet pet in _pets)
{
bool wantedSpecies = true;
foreach (Pet pet2 in _pets)
{
if (pet2 != pet && pet.Species == pet2.Species)
{
wantedSpecies = false;
break;
}
}
if (wantedSpecies) yield return pet;
}
}
我的代码的时间复杂度是多少,我所知道的是它小于O(N ^ 2)并且如果我将从内部foreach循环中删除“break”,则时间复杂度将为O(N ^ 2)。如果我错了,请纠正我。
答案 0 :(得分:2)
以下是我的看法:
var q = list.GroupBy (l => l.Species)
.Where (l => l.ElementAtOrDefault(1) == null)
.Select (l => l.Key)
GroupBy
将在内部使用HashSet,因此O(N)
ElementAtOrDefault(1)
只需要将枚举器移动一步,这样不就是O(n)
答案 1 :(得分:1)
我认为这段代码做同样的事情。在那种情况下,这是O(N)算法。诀窍是将宠物存放在由物种索引的字典中。
public IEnumerable<Pet> speciesChecker()
{
var species = new Dictionary<Species, List<Pet>>();
foreach (Pet pet in _pets)
{
// create the list if it doesn't exist
if (!species.ContainsKey(pet.Species))
species[pet.Species] = new List<Pet>();
species[pet.Species].Add(pet);
}
// foreach species, if there is only one pet of that species, then return it
foreach (var speciesPets in species.Values)
{
if (speciesPets.Count() == 1)
yield return speciesPets.First();
}
yield break;
}
答案 2 :(得分:1)
您还可以使用以下内容,也应该是O(N):
public IEnumerable<Pet> speciesChecker ()
{
_pets.GroupBy (p => p.Species)
.Select (g => new List<Pet> (g))
.Where (l => l.Count == 1)
.SelectMany (l => l);
}
额外Select (g => new List<Pet> (g))
可能是多余的,但我相信这有助于避免第二次迭代整个分组逻辑,我相信会导致O(N ^ 2)。
编辑:来自Magnus的关于在O(n)中运行的List构造函数的好评如果......
怎么样:
public IEnumerable<Pet> speciesChecker ()
{
var groups = _pets.GroupBy (p => p.Species);
foreach (var grp in _pets.GroupBy (p => p.Species))
using (var e = grp.GetEnumerator ()) {
if (!e.MoveNext ())
continue;
var first = e.Current;
if (e.MoveNext ())
continue;
yield return first;
}
}
我认为这是最优化的,并且可以在O(n)中工作。我们也避免使用IEnumerable<T>.Any ()
或IEnumerable<T>.Count ()
扩展方法。
思想?
答案 3 :(得分:0)
让n
为_pets collection
中断所需的步骤数:
1+2+3+...+n = n*(n+1)/2 =n^2/2 + n/2 = O(n^2) (for each pet in _pets);
如何从wiki计算O有两个简单的规则:
如果f(x)是几个项的总和,那么最大的一个 保留增长率,并忽略所有其他增长率。 p>
如果f(x)是几个因子的乘积,则任何常数(术语in 不依赖于x的产品被省略。
不间断所需的步骤数:
n+n+n+...+n = n^2 = O(n^2)