Вы легко отделались, вы, вероятно , не хотите работать в хедж-фонде, где кванты не понимают базовых алгоритмов :-)
Там нет не способа обработать произвольно размер структуру данных в O(1)
случае, так как в этом случае, вы должны посетить каждый элемент , по крайней мере один раз. Лучше вы можете надеяться на то , O(n)
в этом случае, когда n
это длина строки.
Хотя, как и в стороне, номинальный O(n)
алгоритм будет иметь O(1)
для размера фиксированного ввода так, технически, они , возможно, были правильными здесь. Однако обычно люди используют анализ сложности не так.
Мне кажется, вы могли произвести на них впечатление разными способами.
Во- первых, сообщив им , что это не возможно сделать это O(1)
, если вы не использовать «подозреваемый» рассуждения , приведенные выше.
Во-вторых, продемонстрировав свои элитные навыки, предоставив код Pythonic, например:
inpStr = '123412345123456'
freq = [0] * 1000
for val in [int(inpStr[pos:pos+3]) for pos in range(len(inpStr) - 2)]:
freq[val] += 1
print ([(num, freq[num]) for num in range(1000) if freq[num] > 1])
Это выводит:
[(123, 3), (234, 3), (345, 2)]
хотя вы, конечно, можете изменить выходной формат на все, что захотите.
И, наконец, сообщив им, что почти наверняка нет проблем с O(n)
решением, поскольку приведенный выше код предоставляет результаты для строки из одного миллиона цифр менее чем за полсекунды. Кажется, что он также масштабируется довольно линейно, поскольку строка из 10 000 000 символов занимает 3,5 секунды, а строка из 100 000 000 символов - 36 секунд.
И, если им нужно что-то получше, есть способы распараллелить подобные вещи, которые могут значительно ускорить это.
Конечно, не в рамках одного интерпретатора Python из-за GIL, но вы можете разделить строку на что-то вроде ( vv
для правильной обработки граничных областей требуется перекрытие, обозначенное значком):
vv
123412 vv
123451
5123456
Вы можете разделить их на отдельных рабочих, а затем объединить результаты.
Разделение входных данных и объединение выходных данных может затопить любую экономию небольшими строками (и, возможно, даже строками из миллионов цифр), но для гораздо больших наборов данных это вполне может иметь значение. Моя обычная мантра «измеряйте, а не угадайте» , конечно, применима здесь.
Эта мантра также применима к другим возможностям, таким как полный обход Python и использование другого языка, который может быть быстрее.
Например, следующий код C, работающий на том же оборудовании, что и предыдущий код Python, обрабатывает сто миллионов цифр за 0,6 секунды, примерно столько же времени, сколько код Python обработал один миллион. Другими словами, намного быстрее:
#include <stdio.h>
#include <string.h>
int main(void) {
static char inpStr[100000000+1];
static int freq[1000];
memset(inpStr, '1', sizeof(inpStr));
inpStr[sizeof(inpStr)-1] = '\0';
if (strlen(inpStr) <= 2) return 0;
int val = (inpStr[0] - '0') * 10 + inpStr[1] - '0';
char *inpPtr = &(inpStr[2]);
while (*inpPtr != '\0') {
val = (val % 100) * 10 + *inpPtr++ - '0';
freq[val]++;
}
for (int i = 0; i < 1000; ++i)
if (freq[i] > 1)
printf("%3d -> %d\n", i, freq[i]);
return 0;
}