РЕДАКТИРОВАТЬ: я понял, как только я поставил, что это действительно работает только для наборов - он не будет правильно работать с коллекциями, которые имеют дубликаты предметов. Например, {1, 1, 2} и {2, 2, 1} будут считаться равными с точки зрения этого алгоритма. Однако если ваши коллекции являются наборами (или их равенство можно измерить таким образом), я надеюсь, что вы найдете следующее полезным.
Решение, которое я использую:
return c1.Count == c2.Count && c1.Intersect(c2).Count() == c1.Count;
Linq делает словарь под обложками, так что это тоже O (N). (Обратите внимание, это O (1), если коллекции не одного размера).
Я сделал проверку работоспособности, используя метод "SetEqual", предложенный Дэниелом, метод OrderBy / SequenceEquals, предложенный Игорем, и мое предложение. Ниже приведены результаты, показывающие O (N * LogN) для Игоря и O (N) для моего и Дэниела.
Я думаю, что простота кода пересечения Linq делает его предпочтительным решением.
__Test Latency(ms)__
N, SetEquals, OrderBy, Intersect
1024, 0, 0, 0
2048, 0, 0, 0
4096, 31.2468, 0, 0
8192, 62.4936, 0, 0
16384, 156.234, 15.6234, 0
32768, 312.468, 15.6234, 46.8702
65536, 640.5594, 46.8702, 31.2468
131072, 1312.3656, 93.7404, 203.1042
262144, 3765.2394, 187.4808, 187.4808
524288, 5718.1644, 374.9616, 406.2084
1048576, 11420.7054, 734.2998, 718.6764
2097152, 35090.1564, 1515.4698, 1484.223