Вот подход O (max (x) + len (x)) с использованием scipy.sparse
:
import numpy as np
from scipy import sparse
x = np.array("1 2 2 0 0 1 3 5".split(),int)
x
# array([1, 2, 2, 0, 0, 1, 3, 5])
M,N = x.max()+1,x.size
sparse.csc_matrix((x,x,np.arange(N+1)),(M,N)).tolil().rows.tolist()
# [[3, 4], [0, 5], [1, 2], [6], [], [7]]
Это работает путем создания разреженной матрицы с записями в позициях (x [0],0), (x [1], 1), ... Используя формат CSC
(сжатый разреженный столбец), это довольно просто. Затем матрица преобразуется в формат LIL
(связанный список). Этот формат хранит индексы столбцов для каждой строки в виде списка в атрибуте rows
, поэтому все, что нам нужно сделать, это взять его и преобразовать в список.
Обратите внимание, что для небольших массивов argsort
основанные решениявероятно, быстрее, но при некоторых не слишком больших размерах это пересекается.