Попереднє 65-байтне рішення:
r->{for(int a,b=0,z,i=0;;b=a)if((a=b|1<<(z=r[i++]))==b)return z;}
Нове рішення. 19 байт включено дляimport java.math.*;
-8 байт завдяки @Nevay
r->{int z,i=0;for(BigInteger c=BigInteger.ZERO;c.min(c=c.setBit(z=r[i++]))!=c;);return z;}
Спробуйте в Інтернеті!
Редагувати
Алгоритм у моїй початковій програмі був чудовим, але статичний розмір використовуваного типу даних означав, що він швидко порушився, коли розмір перевищив певний поріг.
Я змінив тип даних, що використовується в обчисленні, щоб збільшити ліміт пам'яті програми для її задоволення (використовуючи BigInteger
для довільної точності замість int
або long
). Однак це робить дискусійним, чи вважається це O(1)
складністю простору чи ні .
Я залишу своє пояснення нижче недоторканим, але хочу додати, що зараз я вважаю, що цього неможливо досягти O(1)
космічної складності без певних припущень.
Доказ
Визначте N
як ціле число таке, що2 <= N
.
Дозвольте S
бути списком, що представляє серію випадкових цілих чисел [x{1}, ..., x{N}]
, де x{i}
є обмеження1 <= x{i} <= N
.
Часова складність (у позначенні Big-O), необхідна для повторення цього списку рівно один раз на елемент O(n)
Завдання, яке задається, - знайти перше дублюване значення у списку. Більш конкретно, ми шукаємо перше значення вS
тому, що є дублікатом попереднього елемента в списку.
Нехай p
і q
будуть позиції двох елементів у списку такі, що p < q
і x{p} == x{q}
. Нашим завданням стає пошук найменшого, q
який відповідає цим умовам.
Очевидним підходом до цієї проблеми є повторення через S та перевірка, чи x{i}
існує в іншому списку T
: Якщо x{i}
його не існує T
, ми зберігаємо його T
. Якщо x{i}
воно існує в T
, воно є першим повторюваним значенням і, отже, найменшим q
, і як таке ми повертаємо його. Ця космічна ефективність є O(n)
.
Для досягнення O(1)
просторової складності при збереженні просторової складності необхідно: 1. N задано верхню межу, відповідну пам'яті, необхідній для зберігання максимальної кількості можливих значень для конкретного кінцевого типу даних. 2. Перепризначення однієї незмінної змінної не враховується за складністю, лише кількість змінних (список містить декілька змінних). 3. (На основі інших відповідей) Список (або, принаймні, елементи списку) є змінним, а тип даних списку задається як підписане ціле число, що дозволяє вносити зміни до елементів далі у списку без використання додаткової пам'яті.O(n)
часової складності нам потрібно зберігати унікальну інформацію про кожен об’єкт у списку у обмеженому просторі. Через це єдиний спосіб роботи будь-якого алгоритмуO(1)
1 і 3 вимагають припущень та специфікацій щодо типу даних, тоді як 2 вимагає, щоб для обчислення складності простору враховувалося лише кількість змінних, а не розмір цих змінних. Якщо жодне з цих припущень не буде прийнято, досягти як O(n)
часової складності, так і O(1)
просторової складності було б неможливо .
Пояснення
Хлопчик, цей хлопчик зайняв тривожно довгий час, щоб придумати трохи сили мозку.
Отже, їхати на бонус складно. Нам потрібно обом оперувати над усім списком рівно один раз і відслідковувати, які значення ми вже повторили, без додаткової складності простору.
Бітова маніпуляція вирішує ці проблеми. Ми ініціалізуємо наше O(1)
«сховище», пару цілих чисел, а потім повторимо список, АБО - і-й біт у нашому першому цілому і збережемо результат у другому.
Наприклад, якщо у нас є 1101
і ми виконуємо операцію АБО 10
, ми отримуємо 1111
. Якщо ми зробимо ще АБО з 10
, у нас все ще є 1101
.
Ерго, як тільки ми виконаємо операцію АБО і закінчимо тим самим числом, ми знайшли наш дублікат. Жоден дублікат у масиві не спричиняє перебіг програми та викидання виключення.