Меня слегка смущает, что вы просите O (n), поэтому не стесняйтесь меня поправлять, но, насколько я могу судить, O (n) легко возможно.
Сначала найдите длину вашего начального хэша (количество серий в данных). Это должно быть O (1), но не хуже, чем O (S) (где S не является последовательностью), а S <= O (n) (при условии, что нет ряда без значений), так что все равно O (n). </p>
Сохраните эту длину где-нибудь, а затем настройте хэш для разреженной матрицы, чтобы автоматически инициализировать любую строку пустым массивом этого размера.
matrix = Hash.new {|hsh,k| hsh[k] = Array.new(S)}
Затем просто просмотрите каждую серию по индексу. И для каждой записи установите подходящую ячейку в массиве для правильного значения.
Для каждой записи это O (1) (среднее) для поиска метки времени в хэше, затем O (1) для установки ячейки в массиве. Это случается n раз, давая вам O (n) там.
Также будет создание массива для каждой строки в матрице. Насколько мне известно, это O (1) для одного массива, поэтому O (T) (где T - количество временных меток) в целом. Поскольку мы не создаем пустые строки, в которых нет записей с этой отметкой времени, T должно быть <= n, так что это тоже O (n). </p>
Итак, в целом мы имеем O (n) + O (n) + O (n) = O (n). Вероятно, есть способы ускорить это в Ruby, но, насколько мне известно, это не только близко, но на самом деле O (n).