Знайдіть перший дублюючий елемент


39

Враховуючи масив a, який містить лише числа в діапазоні від 1 до a.length, знайдіть перше дублікальне число, для якого друге входження має мінімальний індекс. Іншими словами, якщо є більше 1 дублюваних чисел, поверніть число, для якого другий випадок має менший індекс, ніж другий вхід іншого числа. Якщо таких елементів немає, у вашій програмі / функції може виникнути невизначена поведінка.

Приклад:

Бо a = [2, 3, 3, 1, 5, 2]вихід повинен бути firstDuplicate(a) = 3.

Є 2 дублікати: числа 2 і 3. Другий випадок 3 має менший індекс, ніж другий випадок у 2, тому відповідь - 3.

Бо a = [2, 4, 3, 5, 1]вихід повинен бути firstDuplicate(a) = -1.

Це , тому найкоротша відповідь у байтах виграє.

БОНУС: Чи можете ви вирішити це в O (n) часовій складності та O (1) додатковій складності простору?


Коментарі не для розширеного обговорення; ця розмова переміщена до чату .
Мартін Ендер

Відповіді:


15

Python 2 , 34 байти

O (n 2 ) час, O (n) простір

Збережено 3 байти завдяки @vaultah та ще 3 від @xnor!

lambda l:l[map(l.remove,set(l))<0]

Спробуйте в Інтернеті!


1
Це виглядає як lambda l:l[map(l.remove,set(l))<0]твори, хоча порядок оцінювання дивний.
xnor

Це не повертається, -1коли жодних дублікатів не знайдено без "коду колонтитула", чи не зараховується цей код до байтів? Я новачок в коді гольфу, вибачте, якщо це основне питання!
Chris_Rands

@Chris_Rands Під запитанням музикант запитав, якщо виняток є нормальним замість -1, а ОП сказав, що добре, а відповідь музиканта кидає виняток.
LiefdeWen

Це знадобило мені час, щоб розібратися. Гарно зіграно. Отримати 0-й елемент l за допомогою умовного після його модифікації дійсно розумно.
Thoth19

Чи гарантує Python складність часу та простору стандартних функцій бібліотеки типу set.remove?
Драконіс

11

JavaScript (ES6), 47 36 31 25 байт

Збережено 6 байт завдяки ThePirateBay

Повертається, undefinedякщо рішення не існує.

Часова складність: O (n) :-)
Складність простору: O (n) :-(

a=>a.find(c=>!(a[-c]^=1))

Як?

Ми відслідковуємо вже зустрічаються значення, зберігаючи їх як нові властивості вихідного масиву a , використовуючи від’ємні числа. Таким чином, вони не можуть втручатися в оригінальні записи.

Демо


25 байт:a=>a.find(c=>!(a[-c]^=1))

@ ThePirateBay О, звичайно. Спасибі!
Арнольд

Просто зауважте, що об’єкти в JavaScript можуть не бути реалізовані як хеш-таблиця. Часова складність доступу до ключів певного об'єкта може бути не O (1).
tsh

6

Математика, 24 байти

#/.{h=___,a_,h,a_,h}:>a&

Можливість узгодження зразків Mathematica настільки класна!

Повертає оригінал Listдля недійсного введення.

Пояснення

#/.

На вводі замініть ...

{h=___,a_,h,a_,h}

А Listз дублюючим елементом, з 0 або більше елементами до, між та після дублікатів ...

... :>a

З дублюючим елементом.


6

Желе , 5 байт

Ṛœ-QṪ

Спробуйте в Інтернеті!

Як це працює

Ṛœ-QṪ  Main link. Argument: A (array)

Ṛ      Yield A, reversed.
   Q   Unique; yield A, deduplicated.
 œ-    Perform multiset subtraction.
       This removes the rightmost occurrence of each unique element from reversed
       A, which corresponds to the leftmost occurrence in A.
    Ṫ  Take; take the rightmost remaining element, i.e., the first duplicate of A.

œ-видаляє найправіші події? TIL
Erik the Outgolfer

Схоже, це не повертається -1без жодних дублікатів. Викинути виняток - це нормально згідно з ОП, але я не впевнений, чи 0є він, хоча це не в діапазоні.
Ерік Аутгольфер


4

Желе , 6 байт

xŒQ¬$Ḣ

Спробуйте в Інтернеті!

Повертає перший дублікат, або 0, якщо немає дубліката.

Пояснення

xŒQ¬$Ḣ  Input: array M
    $   Operate on M
 ŒQ       Distinct sieve - Returns a boolean mask where an index is truthy
          for the first occurrence of an element
   ¬      Logical NOT
x       Copy each value in M that many times
     Ḣ  Head

Це golfier використовувати індексацію як це: ŒQi0ị.
Ерік Аутгольфер

@EriktheOutgolfer Якщо дублікатів немає, i0повертається 0, де індексує та повертає останнє значення вводу замість 0.
миль

4

Japt , 7 байт

æ@bX ¦Y

Перевірте це в Інтернеті!

Пояснення

 æ@   bX ¦ Y
UæXY{UbX !=Y}  Ungolfed
               Implicit: U = input array
UæXY{       }  Return the first item X (at index Y) in U where
     UbX         the first index of X in U
         !=Y     is not equal to Y.
               In other words, find the first item which has already occured.
               Implicit: output result of last expression

Як варіант:

æ@¯Y øX

Перевірте це в Інтернеті!

Пояснення

 æ@   ¯ Y øX
UæXY{Us0Y øX}  Ungolfed
               Implicit: U = input array
UæXY{       }  Return the first item X (at index Y) in U where
     Us0Y        the first Y items of U (literally U.slice(0, Y))
          øX     contains X.
               In other words, find the first item which has already occured.
               Implicit: output result of last expression

4

Pyth, 5 байт

h.-Q{

Тестовий набір

Видаліть із Q першу появу кожного елемента в Q, а потім поверніть перший елемент.


@LuisMendo Добре дякую. Вибачте за те, що створили плутанину, я повинен навчитися читати ...
Містер Xcoder

@ Mr.Xcoder Ні, це вина ОП. Ця інформація повинна бути в тексті виклику, але лише у коментарі
Луїс Мендо

4

Діалог APL, 27 24 20 19 13 12 11 байт

⊢⊃⍨0⍳⍨⊢=⍴↑∪

Тепер модифіковано, щоб не залежати від v16! Спробуйте в Інтернеті!

Як? (З введенням N )

  • ⊢⊃⍨...- N за цим показником:
    • ⍴↑∪- N із видаленими дублікатами, з правою підкладкою, 0щоб відповідати N
    • ⊢=- Елементно рівність з N
    • 0⍳⍨- Покажчик першого 0. `

ніколи не розумію, я неправильно прочитав питання. не вистачає тестових випадків, хоча ...
Уріель

Вибачте за те, що вас ввели в оману, я також неправильно прочитав питання.
милі

Схоже, мені 36 байт.
Adám

О боже, йота підніжжя не знаходиться ⎕AV, чи не так?
Zacharý

@ Zacharý Право, Класичний перекладає це під ⎕U2378 час завантаження. Спробуйте в Інтернеті!
Adám

3

Python 3 , 94 92 байт

O (n) час та O (1) додаткова пам'ять.

def f(a):
 r=-1
 for i in range(len(a)):t=abs(a[i])-1;r=[r,i+1][a[t]<0>r];a[t]*=-1
 return r

Спробуйте в Інтернеті!

Джерело алгоритму .

Пояснення

Основна ідея алгоритму полягає в тому, щоб пробігти кожен елемент зліва направо, відстежувати числа, що з’явилися, і повертати число, досягнувши числа, яке вже з’явилося, і повернути -1 після проходження кожного елемента.

Однак він використовує розумний спосіб зберігання цифр, які з’явилися без використання додаткової пам'яті: зберігати їх як знак елемента, індексованого номером. Наприклад, я можу представити той факт, що 2і 3вже з’явився, маючи a[2]та a[3]негатив, якщо масив є 1-індексованим.


Що б це зробило для iде [i]> n?
Пуховик

@Downgoat знову прочитав питання.
Leaky Nun

Питання відповідає 1a.length, але для [i] = a.length чи це не вийде за межі?
Пуховик

@Downgoatt=abs(a[i])-1=a.length-1
Leaky Nun


3

Perl 6 , 13 байт

*.repeated[0]

Спробуй це


Пояснення

  • *Знаходиться в положенні Term тому все твердження є WhateverCode лямбда.

  • Це .repeatedметод, який призводить до кожного значення, за винятком того, як вперше було видно кожне значення.

    say [2, 3, 3, 3, 1, 5, 2, 3].repeated.perl; # (3, 3, 2, 3).Seq
    #   (      3, 3,       2, 3).Seq
  • [0]просто повертає перше значення в Seq .
    Якщо немає значення, Nil повертається.
    ( Nil - основа типів Failure , і всі типи є їх власним невизначеним значенням, тому Nil відрізняється від невизначеного значення у більшості інших мов)


Зауважте, що оскільки реалізація.repeated генерує Seq, це означає, що вона не починає виконувати будь-яку роботу, поки ви не попросите значення, і вона лише зробить достатньо роботи, щоб генерувати те, що вам потрібно.
Тож було б легко стверджувати, що це в гіршому випадку O (n)  часову складність, а в кращому випадку O (2)  часову складність, якщо друге значення є повторенням першого.
Можливо, подібне можна сказати про складність пам'яті.


3

APL (Діалог) , 20 байт

n/⍨(,≢∪)¨,\n←⎕,2⍴¯1

Спробуйте в Інтернеті!

2⍴¯1 від'ємний r сформований у списку довжиною дві

⎕, отримати вхід (мнемонічний: консольний ящик) і додати до цього

n← зберігати, що в н

,\ префікси n (літ. кумулятивна конкатенація)

( Застосувати наступну функцію мовчання до кожного префікса

, [є] ravel (просто гарантує, що префікс є списком)

 відрізняється від

 унікальні елементи [?] (тобто чи має префікс дублікати?)

n/⍨ використовувати це для фільтрації n (видаляє всі елементи до першого, для якого було знайдено дублікат)

 виберіть перший елемент із цього


Нічого собі, тебе тричі били. Все-таки +1. А чи можете ви додати пояснення, як це працює?
Zacharý

@ Zacharý Мабуть, мені просто потрібно було прокатати м'яч. Ось ви йдете.
Adám


3

APL (Діалог) , 11 байт

Відповідно до нових правил , видає помилку, якщо не існує дублікатів.

⊢⊃⍨⍬⍴⍳∘≢~⍳⍨

Спробуйте в Інтернеті!

⍳⍨ показники першого появи кожного елемента

~ видалено з

⍳∘≢ усіх показників

⍬⍴ змінити форму в скаляр (дає нуль, якщо немає даних)

⊃⍨ використовувати це для вибору (дає помилку на нуль)

 аргумент


Ну так, коли правила будуть змінені, звичайно, ви можете їх усіх перемогти!
Zacharý

Ну, я тебе зв'язав.
Zacharý

3

APL, 15

{⊃⍵[(⍳⍴⍵)~⍵⍳⍵]}

Здається, ми можемо повернути 0 замість -1, коли немає дублікатів (спасибі Адаму за коментар). Так на 3 байти менше.

Трохи опису:

⍵⍳⍵         search the argument in itself: returns for  each element the index of it's first occurrence
(⍳⍴⍵)~⍵⍳⍵   create a list of all indexes, remove those found in ⍵⍳⍵; i.e. remove all first elements
⊃⍵[...]     of all remaining elements, take the first. If the array is empty, APL returns zero

Для довідки, старе рішення додало -1 до списку в кінці, тож якщо список закінчився порожнім, він міститиме -1, а перший елемент буде -1.

{⊃⍵[(⍳⍴⍵)~⍵⍳⍵],¯1}

Спробуйте це на tryapl.org


Ви можете повернути нуль замість¯1 , як це {⊃⍵[(⍳⍴⍵)~⍵⍳⍵]}слід зробити.
Adám

3

Сітківка , 26 24 байти

1!`\b(\d+)\b(?<=\b\1 .*)

Спробуйте в Інтернеті! Пояснення: \b(\d+)\bпо черзі відповідає кожному номеру, а потім оглядається, щоб побачити, чи є число дублікатом; якщо це виходить 1перший збіг !, а не кількість матчів. На жаль, на перший погляд вигляд не працює, інакше це дозволить зберегти кілька байтів. Редагувати: Додано 7 байт, щоб відповідати -1значенню повернення без відповідності. Збережено 2 байти завдяки @MartinEnder.


2
Для запису, орієнтування не буде відхилятися. Це запобігає роботі, якщо ви спробуєте поставити її раніше. Я багато разів робив цю помилку, і Мартін мене завжди виправляє.
FryAmTheEggman


@ValueInk Але правильна відповідь для цього тестового випадку - 3 ...
Ніл

ОН. Я неправильно прочитав виклик, підкреслив
Value Ink

2

MATL , 8 байт

&=Rsqf1)

Подає помилку (без виводу), якщо не існує дубліката.

Спробуйте в мережі MATL!

Пояснення

&=   % Implict input. Matrix of all pairwise equality comparisons
R    % Keep the upper triangular part (i.e. set lower part to false)
s    % Sum of each column
q    % Subtract 1
f    % Indices of nonzero values
1)   % Get first. Gives an error is there is none. Implictly display

2

R, 34 байти

c((x=scan())[duplicated(x)],-1)[1]

Виріжте кілька персонажів з відповіді від @djhurio, хоча у вас недостатньо репутації для коментарів.


о ... я не бачив цієї відповіді; це добре для попередньої специфікації, коли потрібні відсутні значення-1 але з новою специфікацією я зумів ще більше знизити його. Це все ще твердо, і це інший підхід від того, як він це зробив, тому я дам вам +1!
Джузеппе

2

J, 17 16 байт

(*/{_1,~i.&0)@~:

Як?

(*/{_1,~i.&0)@~:

             @~: returns the nub sieve which is a vector with 1 for the first occurrence of an element in the argument and 0 otherwise

        i.&0     returns the first index of duplication

    _1,~         appends _1 to the index

 */              returns 0 with duplicates (product across nub sieve)

     {           select _1 if no duplicates, otherwise return the index


2

J , 12 байт

,&_1{~~:i.0:

Спробуйте в Інтернеті!

Пояснення

,&_1{~~:i.0:  Input: array M
      ~:      Nub-sieve
          0:  The constant 0
        i.    Find the index of the first occurrence of 0 (the first duplicate)
,&_1          Append -1 to M
    {~        Select the value from the previous at the index of the first duplicate

2

Dyalog APL Classic, 18 символів

Працює лише в ⎕IO←0.

     w[⊃(⍳∘≢~⍳⍨)w←¯1,⎕]

Вийміть зі списку індексів елементів аргументу заздалегідь попередній "-1" список індексів його нубу, а потім виберіть перший із того, що залишилося. Якщо після видалення залишається лише порожній вектор, його першим елементом є визначення 0, яке використовується для індексації розширеного аргументу, створюючи потрібний -1.


Гм ... що з випадковими провідними просторами? +1 - перевершив мене на один байт.
Zacharý

Ви можете викинути помилку замість повернення¯1 , щоб ви могли її видалити ¯1,та використовувати ⎕IO←1.
Адам


2

Java (OpenJDK 8) , 65 117 109 байт

Попереднє 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.

Ерго, як тільки ми виконаємо операцію АБО і закінчимо тим самим числом, ми знайшли наш дублікат. Жоден дублікат у масиві не спричиняє перебіг програми та викидання виключення.


Крім того, ваш другий тест включає число 100, але це неможливо, оскільки сам масив довгий лише 5
SchoolBoy

Крім того, це не вдається, оскільки в int недостатньо місця для зберігання.
SchoolBoy

@SchoolBoy Хороший улов. Моя єдина проблема полягає в тому, що, здається, немає верхньої межі розміру масиву, тому я не можу реально змінити свій код для вирішення проблем із пам'яттю.
Xanderhall

@Xanderhall Щоправда, але я відчуваю, що 32 (або якщо ви використовуєте довгі 64) цифри занадто мало: p. Так чи інакше, накладення обмеження на вхід, а потім розподілення максимально необхідної пам'яті та називання її O (1) пам'яттю - це лише обман. Це все ще O (n), оскільки якби розмір вхідного сигналу збільшився, то це було б верхньою межею пам'яті. І тому я вважаю, що неможливо створити алгоритм O (n) O (1)
SchoolBoy

@Xanderhall PS Я наближаюся до ваших 65, я в 67 байтах: p
SchoolBoy

2

PHP, 56 44 38 32 байт

for(;!${$argv[++$x]}++;);echo$x;

Бігайте так:

php -nr 'for(;!${$argv[++$x]}++;);echo$x;' -- 2 3 3 1 5 2;echo
> 3

Пояснення

for(
  ;
  !${                 // Loop until current value as a variable is truthy
    $argv[++$x]       // The item to check for is the next item from input
  }++;                // Post increment, the var is now truthy
);
echo $x;              // Echo the index of the duplicate.

Налаштування

  • Збережено 12 байт за допомогою змінних замість масиву
  • Збережено 6 байт, використовуючи правило "невизначеної поведінки", коли немає відповідності.
  • Збережено 6 байт, використовуючи посткраста замість встановлення 1 на кожен цикл

Складність

Як видно з коментованої версії коду, часова складність лінійна O(n). Що стосується пам'яті, n+1то буде призначено максимум змінних. Так це O(n).


Дякуємо, що не використовуєте дивне кодування. Але вам слід додати error_reportingпараметр до кількості байтів (або використання -n, яке є безкоштовним).
Тит

Ми тут були раніше. Повідомлення та попередження PHP нехтують. Я б також міг їх передати /dev/null, що те саме.
1717

Я схильний пам’ятати неправильні коментарі. :) Хіба це не О (п)?
Тит

Так, це лінійно
1717

Як це O(1)для додаткового простору? Ви буквально присвоюєте нову змінну per n, якаO(n)
Xanderhall

2

Java 8, 82 78 76 байт більше не життєздатний, 75 67 64 байт нижче в редагуванні

Як лямбда-функція:

a->{Set<Long>s=new HashSet<>();for(long i:a)if(!s.add(i))return i;return-1;}

Напевно, можна зробити набагато менше, це було дуже швидко.

Пояснення:

a->{                                //New lambda function with 'a' as input
    Set<Long>s=new HashSet<>();     //New set
    for(long i:a)                   //Iterate over a
        if(!s.add(i))               //If can't add to s, already exists
            return i;               //Return current value
        return-1;                   //No dupes, return -1
}

* Редагувати *

75 67 64 байт, використовуючи стратегію заперечення:

a->{int i=0,j;while((a[j=Math.abs(a[i++])-1]*=-1)<0);return++j;}

Спробуйте в Інтернеті!

(-3 байти завдяки @Nevay)

Пояснення:

a->{                                         //New lambda expression with 'a' as input
    int i=0,j;                               //Initialise i and declare j
    while((a[j=Math.abs(a[i++])-1]*=-1)<0);  //Negate to keep track of current val until a negative is found
    return++j;                               //Return value
}

Петлі над масивом, нехтуючи відстеженням. Якщо немає дупів, просто перебігає і видає помилку.

Обидва вони працюють на O (n) час та O (n) складність простору.


Варто зазначити, що це потрібно буде призначити лямбді, що повертається Number, оскільки iце є longі -1є int.
Якоб

@Jakob Не потрібно, -1, будучи інтом, автоматично буде передано на довге, не чітко вказуючи кастинг
SchoolBoy

Це буде приховано неявно long, але не так, Longяк потрібно для того, щоб лямбда була призначена а Function. Ви тестували це? Незалежно від цього рішення можна замінити новим.
Якоб

Ви можете використовувати необроблені типи, Set s=new HashSet();щоб зберегти 7 байт. (Крім того: afaik імпорт java.util.*;має бути включений до числа байтів -> +19 байт.) Оперативом return може бути return++j, а оператор if може бути видалений a->{int i=0,j;for(;(a[j=Math.abs(a[i++])-1]*=-1)<0;);return++j;}(-3 байти).
Невай

2

Брахілог , 5 байт

a⊇=bh

Спробуйте в Інтернеті!

Пояснення

a⊇=bh  Input is a list.
a      There is an adfix (prefix or suffix) of the input
 ⊇     and a subsequence of that adfix
  =    whose elements are all equal.
   b   Drop its first element
    h  and output the first element of the rest.

Вбудований adfix aмістить спочатку всі префікси у порядку збільшення довжини, потім суфікси у порядку зменшення довжини. Таким чином, вихід отримується найкоротшим префіксом, який дозволяє, якщо він є. Якщо у префікса немає дублікатів, решта програми відмовляється від нього, оскільки кожна послідовність рівних елементів має довжину 1, а перший елемент його хвоста не існує. Якщо в префіксі є повторний елемент, ми можемо вибрати послідовність довжини-2, що містить обидва, і програма повертає останній.


Ще 5 байт-рішення:, a⊇Ċ=hяке розглядає лише підмножини довжини-2.
Фаталізувати

1

C #, 145 байт

using System.Linq;a=>{var d=a.Where(n=>a.Count(t=>t==n)>1);return d.Select((n,i)=>new{n,i}).FirstOrDefault(o=>d.Take(o.i).Contains(o.n))?.n??-1;}

Можливо, набагато коротший спосіб зробити це в C # за допомогою простого циклу, але я хотів спробувати це з Linq.

Спробуйте в Інтернеті!

Повна / відформатована версія:

namespace System.Linq
{
    class P
    {
        static void Main()
        {
            Func<int[], int> f = a =>
            {
                var d = a.Where(n => a.Count(t => t == n) > 1);
                return d.Select((n, i) => new { n, i }).FirstOrDefault(o => d.Take(o.i).Contains(o.n))?.n ?? -1;
            };

            Console.WriteLine(f(new[] { 2, 3, 3, 1, 5, 2 }));
            Console.WriteLine(f(new[] { 2, 4, 3, 5, 1 }));

            Console.ReadLine();
        }
    }
}

Ось простий варіант циклу. Але мені більше подобається версія Linq.
LiefdeWen

@LiefdeWen Опублікуйте це як відповідь :) Хоча зазвичай мені теж подобається Linq :) Можливо, я можу скоротити її і з Linq, але я зараз впевнений.
TheLethalCoder

Ні, це запитання перенаселене, і я би скоріше за все отримав голоси за це питання.
LiefdeWen

1

Haskell , 78 69 байт

 fst.foldl(\(i,a)(j,x)->(last$i:[j|i<0,elem x a],x:a))(-1,[]).zip[1..]

Спробуйте в Інтернеті!

Збережено 9 байт завдяки @nimi

Основний шлях через список. Якщо поточний елемент ще не бачив ( i<0) і знаходиться у списку акумуляторів ( elem x a), зберігайте поточний індекс. Інше, зберегти індекс -1. У будь-якому випадку додайте поточний елемент до списку акумуляторів.

EDIT : Я недостатньо уважно прочитав питання: цей код видає індекс другого елемента дублюючого елемента.


Ви можете використовувати «Шортер умовний» з наших «Рад для гри в гольф в Haskell» : \ ... ->(last$i:[j|i<0,elem x a],x:a). Також: немає необхідності в f=тому, що дозволені функції без назви.
німі

@nimi дякую за пораду!
jferard

1

Python 2, 71 65 байт

Повертається, Noneякщо немає дублюючого елемента

Редагувати: -6 байт завдяки @ musicman523

def f(n):
 for a in n:
	u=-abs(a)
	if n[u]<0:return-u
	n[u]=-n[u]

Спробуйте в Інтернеті!

O (n) часова складність, O (n) складність простору, O (1) допоміжний простір.

Як список введення використовується O (n) простір , складність простору пов'язана цим. Значить, ми не можемо мати складність простору меншої, ніж O (n)

Чи змінює оригінальний список, якщо це не дозволено, ми могли б зробити це в тій же складності 129 байтами

Пояснення

Оскільки кожен елемент більший за 0 і менше або дорівнює розміру списку, у списку є для кожного елемента a, елемент з індексу a - 1 (0 індексується). Ми використовуємо це, кажучи, що якщо елемент в індексі i від'ємний, ми його бачили і раніше.

Для кожного елемента a у списку n, нехай у від’ємному значенні абсолютне значення a. (Ми дозволяємо йому бути негативним, оскільки python може індексувати списки з негативними індексами, і нам інакше потрібно було б зробити u=abs(a)-1 ) Якщо елемент в індексі u у списку є негативним, ми його бачили раніше і тому можемо повернути -u (щоб отримати абсолютне значення a, оскільки всі елементи позитивні) . В іншому випадку ми встановимо елемент в індексі u негативним, щоб пам’ятати, що ми бачили елемент значення a раніше.


Хороша робота! 65 байт
musicman523

Ви впевнені, що це O (1) в пам'яті? Ви все ще використовуєте n біт пам’яті, щоб зберігати, які цифри вже відвідали, навіть якщо біти знаку. Мені здається, що це О (п) у масках
Пшеничний майстер

Технічно для цього використовується пробіл O (n) - знаки n знаків n. Якщо масив може містити тільки значення між 1і n, наприклад , як це було дано, то це , очевидно , не працює.
Олівер Ні

Це дійсно просто зводиться до представництва, яке ви обираєте для чисел. Якщо використовуються непідписані числа, то це допоміжний простір O (n) . Якщо використовуються підписані номери, то біт знака вже є, що означає O (1) допоміжний простір.
Халвард Гуммель

Я згоден з вами там. Я особисто дозволив би вам ковзати, використовуючи підписані цілі числа, доки ви не використовували біт знаків, це стосується алгоритму, а не технічних можливостей системи. Це, як кажуть, я думаю, якщо ви збираєтесь використовувати знаки бітів, ви повинні їх порахувати. Я думаю, що ця відповідь досить розумна. Якщо у мене сьогодні залишиться якийсь голос, я б схвалив його, щоб протидіяти голосуванню.
Пшеничний майстер

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.