Ви злегка зійшли, ви, мабуть , не хочете працювати в хедж-фонді, де учасники не розуміють основних алгоритмів :-)
Там немає НЕ способу обробити довільно розмір структуру даних в O(1)
разі, так як в цьому випадку, ви повинні відвідати кожен елемент , по крайней мере один раз. Краще ви можете сподіватися на те , O(n)
в цьому випадку, коли n
це довжина рядка.
Хоча, як і осторонь, номінальний O(n)
алгоритм буде встановлений O(1)
для фіксованого розміру вводу, тому технічно вони, можливо, тут були правильними. Однак, як правило, люди не використовують аналіз складності.
Мені здається, ви могли вразити їх різними способами.
По- перше, повідомивши їм , що це НЕ можливо зробити це O(1)
, якщо ви не використовувати «підозрюваний» міркування , наведені вище.
По-друге, показавши свої елітні навички, надавши пітонічний код, наприклад:
inpStr = '123412345123456'
# O(1) array creation.
freq = [0] * 1000
# O(n) string processing.
for val in [int(inpStr[pos:pos+3]) for pos in range(len(inpStr) - 2)]:
freq[val] += 1
# O(1) output of relevant array values.
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];
// Set up test data.
memset(inpStr, '1', sizeof(inpStr));
inpStr[sizeof(inpStr)-1] = '\0';
// Need at least three digits to do anything useful.
if (strlen(inpStr) <= 2) return 0;
// Get initial feed from first two digits, process others.
int val = (inpStr[0] - '0') * 10 + inpStr[1] - '0';
char *inpPtr = &(inpStr[2]);
while (*inpPtr != '\0') {
// Remove hundreds, add next digit as units, adjust table.
val = (val % 100) * 10 + *inpPtr++ - '0';
freq[val]++;
}
// Output (relevant part of) table.
for (int i = 0; i < 1000; ++i)
if (freq[i] > 1)
printf("%3d -> %d\n", i, freq[i]);
return 0;
}