2013-08-10 1 views
0

найти индекс в круговом массиве, чтобы строка, которая формируется, начиная с этого индекса, сначала в лексикографическом порядке.найти лексикографически минимальное вращение строки без дерева суффиксов и в O (n)

Для примера: в круговой массиве ABCDEABCCDE Ответ равен 6, потому что круговая строка, начинающаяся с элемента A в 6-й позиции, входит сначала в словарь, образованный из всех возможных строк круговой массива.

+0

Вы можете легко найти его: сгенерировать все возможные строки (там будет 'n', где' n' - длина исходной строки), а затем просто найти первый, используя линейный поиск/выбор. Обе операции принимают значение «O (n)». –

+0

@ H2CO3: сложность будет очень большой. Я ищу O (n) алгоритм. Ваш подход O (n^2). – jairaj

+0

@jairaj "Очень большой"? Почему? Для генерации подстрок требуется 'O (n)', затем 'O (n)' для поиска минимума. (И вообще, теперь yoyu ищет решение «O (n)» или «O (1)»? Ваш комментарий не соответствует критерию в заголовке.) –

ответ

0

Теория A: Если в последовательности длины N есть K вхождений буквы X, то существует как минимум два вхождения X, так что расстояние между ними меньше N/K.

Найдите минимальную букву и укажите указатели на все ее вхождения в отсортированном списке. Позвоните по этому адресу.

Для данного г найдите минимум букв в A [i] + r и отфильтруйте все указатели, для которых элемент в точке A [i] + r не равен min. Также отфильтруйте все указатели A [j] такие, что A [j] = A [i] + r для некоторого i.

Вам нужно будет выполнить вышеуказанное утверждение не более N/K раз, и каждый прогон будет стоить не более O (K). Поэтому сложность этого алгоритма O (N).

Подробный алгоритм: Предположим, что Z - это круговой список, с которым мы имеем дело.

def filter(A,Z,r): 
    t = min(Z[A[i]+r]) forall i 
    remove A[i] if Z[A[i]+r]!=t forall i 

    rmflag = [false if A[i]==A[j]+r else false for i in range(len(A)] //NOTE: This step can be done in O(len(A)) time since A is sorted 
    remove A[i] if rmflag[i] 
-1
Step 1: find the min char, call it minChar 
Step 2: build list L0 = {i: string[i] == minChar, but string[i-1] != minChar} 
Step 3: if L0.size() == 1, return L0[0] 
step 3: 
     3.0 set k=0, let L = L0 
     3.1 k++ 
     3.2 BUild L1 = {i+1, i in L}. Build L = {i: string[i] is smallest for any k in L1} 
     3.3 If L.size() == 1, return L[0]-k. Otherwise goto 3.1 to repeat 

Это должно дать вам O (N) ожидается сложности.

+0

Я думаю, что ваше решение не подходит для случая, такого как ABABABABABABABABABABAD (в этом случае решение будет O (n^2)) – ElKamina

Смежные вопросы