Давайте переформулируем проблему. Вы хотите написать
foreach(int item in items)
bins[GetBinIndex(item)].Add(item);
так, что производительность GetBinIndex лучше, чем O (n) в количестве бинов.
Это зависит от топологии бункеров.
Если ячейки представляют собой просто непрерывные неотрицательные целочисленные диапазоны, скажем, 0..4, 5..9, 10..14 и т. Д., То просто разделите элемент на 5, готово. Это O (1).
Если ячейки представляют собой непрерывные целочисленные диапазоны разных размеров, скажем, 0..4, 5..14, 15..16, 17..17, 18..32, ... тогда:
- Создайте
List<int>
, в котором хранится вершина каждого диапазона. Так что в этом случае {4, 14, 16, 17, 32, ...}
- BinarySearch список для элемента.
- если результат - неотрицательное число, то это индекс корзины, и у вас есть элемент, находящийся вверху его корзины.
- если результат - отрицательное число, то это дополнение к лучшей корзине, верхний элемент которой больше, чем элемент. Возьмите дополнение индекса, и это мусорное ведро.
Это O (lg n) для поиска и O (n) для построения списка.
Если ячейки представляют собой несмежные целочисленные диапазоны, то есть, если диапазоны имеют дыры или перекрываются, то структура данных, которую вы хотите построить для эффективного поиска наилучшего диапазона, представляет собой дерево интервалов . Деревья интервалов обычно O (lg n) для поиска в непатологических ситуациях и O (n lg n) для построения дерева в первую очередь.