А как насчет использования дерева сплайнов ? Благодаря уникальному подходу Splay Tree к адаптивной балансировке, он обеспечивает плавную реализацию алгоритма с дополнительным преимуществом возможности перечислять элементы x
по порядку. Вот некоторый псевдокод.
public SplayTree GetSmallest(int[] array, int x)
{
var tree = new SplayTree();
for (int i = 0; i < array.Length; i++)
{
int max = tree.GetLargest();
if (array[i] < max || tree.Count < x)
{
if (tree.Count >= x)
{
tree.Remove(max);
}
tree.Add(array[i]);
}
}
return tree;
}
Операции GetLargest
и Remove
имеют амортизированную сложность O (log (n)), но из-за того, что последний доступный элемент всплывает вверх, обычно это O (1). Таким образом, сложность пространства равна O (x), а сложность среды выполнения - O (n * log (x)). Если массив окажется уже упорядоченным, то этот алгоритм достигнет своей сложности в лучшем случае O (n) с возрастающим или убывающим упорядоченным массивом. Однако очень странное или своеобразное упорядочение может привести к сложности O (n ^ 2). Можете ли вы угадать, как массив должен быть упорядочен для этого?