Dada uma matriz a que contém apenas números no intervalo de 1 a a.length, encontre o primeiro número duplicado para o qual a segunda ocorrência possui o índice mínimo. Em outras palavras, se houver mais de 1 número duplicado, retorne o número para o qual a segunda ocorrência possui um índice menor que a segunda ocorrência do outro número. Se não houver tais elementos, seu programa / função poderá resultar em um comportamento indefinido.
Exemplo:
Pois a = [2, 3, 3, 1, 5, 2]
, a saída deve ser
firstDuplicate(a) = 3
.
Existem 2 duplicatas: números 2 e 3. A segunda ocorrência de 3 tem um índice menor que a segunda ocorrência de 2, portanto a resposta é 3.
Pois a = [2, 4, 3, 5, 1]
, a saída deve ser
firstDuplicate(a) = -1
.
Isso é código-golfe , então a resposta mais curta em bytes vence.
BÔNUS: Você pode resolvê-lo em O (n) complexidade de tempo e O (1) complexidade adicional de espaço?
fonte
Respostas:
Python 2 , 34 bytes
O (n 2 ) tempo, O (n) espaço
Economizou 3 bytes graças a @vaultah e mais 3 de @xnor!
Experimente online!
fonte
lambda l:l[map(l.remove,set(l))<0]
funciona, mesmo que a ordem da avaliação seja estranha.-1
quando nenhuma duplicata é encontrada sem o 'código de rodapé', esse código não conta para os bytes? Eu sou novo em codificar golfe, desculpe se é uma pergunta básica!JavaScript (ES6),
47363125 bytesEconomizou 6 bytes graças a ThePirateBay
Retorna
undefined
se não houver solução.Complexidade do tempo: O (n) :-)
Complexidade do espaço: O (n) :-(
Quão?
Nós manter o controle de valores já encontradas por salvá-los como novas propriedades da matriz original um usando números negativos. Dessa forma, eles não podem interferir nas entradas originais.
Demo
Mostrar snippet de código
fonte
a=>a.find(c=>!(a[-c]^=1))
Mathematica, 24 bytes
A capacidade de correspondência de padrões do Mathematica é muito legal!
Retorna o original
List
para entrada inválida.Explicação
Na entrada, substitua ...
A
List
com um elemento duplicado, com 0 ou mais elementos antes, entre e depois das duplicatas ...Com o elemento duplicado.
fonte
Geléia , 5 bytes
Experimente online!
Como funciona
fonte
œ-
remove as ocorrências mais à direita? TIL-1
sem duplicatas. Lançar uma exceção é bom conforme o OP, mas não tenho certeza se0
é mesmo que não esteja no intervalo.Haskell , 35 bytes
Experimente online! Falha se nenhuma duplicata for encontrada.
fonte
Gelatina , 6 bytes
Experimente online!
Retorna a primeira duplicata ou 0 se não houver duplicata.
Explicação
fonte
ŒQi0ị
.i0
retornaria 0, onde indexariaị
e retornaria o último valor da entrada em vez de 0.Japonês , 7 bytes
Teste online!
Explicação
Alternativamente:
Teste online!
Explicação
fonte
Pitão, 5 bytes
Suíte de teste
Remova de Q a primeira aparência de cada elemento em Q e, em seguida, retorne o primeiro elemento.
fonte
Dyalog APL,
27242019131211 bytesAgora modificado para não depender da v16! Experimente online!
Quão? (Com entrada N )
⊢⊃⍨...
- N neste índice:⍴↑∪
- N com duplicatas removidas, acolchoado à direita com o0
tamanho N⊢=
- Igualdade entre elementos com N0⍳⍨
- Índice do primeiro0
. `fonte
⎕AV
, está?⎕U2378
carregamento. Experimente online!Python 3 ,
9492 bytesO (n) tempo e O (1) memória extra.
Experimente online!
Fonte do algoritmo .
Explicação
A idéia básica do algoritmo é percorrer cada elemento da esquerda para a direita, acompanhar os números que apareceram e retornar o número ao atingir um número que já apareceu e retornar -1 depois de percorrer cada elemento.
No entanto, ele usa uma maneira inteligente de armazenar os números que apareceram sem o uso de memória extra: para armazená-los como o sinal do elemento indexado pelo número. Por exemplo, eu posso representar o fato de que
2
e3
já apareceu por tera[2]
ea[3]
negativo, se a matriz estiver indexada em 1.fonte
i
onde um [i]> n?1
a.length, mas para um [i] = a.length isso não sairia dos limites?t=abs(a[i])-1=a.length-1
Perl 6 , 13 bytes
Tente
Explicação
A posição
*
está em um termo, portanto, toda a instrução é uma lambda WhateverCode .O
.repeated
é um método que resulta em todos os valores, exceto pela primeira vez que cada valor foi visto.[0]
apenas retorna o primeiro valor na Seq .Se não houver valor, nada será retornado.
( Nil é a base dos tipos de falha e todos os tipos têm seu próprio valor indefinido, portanto, nulo é diferente de um valor indefinido na maioria dos outros idiomas)
Observe que, como a implementação de
.repeated
gera uma Seq, isso significa que ela não começa a fazer nenhum trabalho até que você solicite um valor, e apenas faz o suficiente para gerar o que você solicita.Portanto, seria fácil argumentar que isso tem, na pior das hipóteses, O (n) complexidade de tempo e, na melhor das hipóteses, O (2) complexidade de tempo se o segundo valor for uma repetição do primeiro.
Provavelmente semelhante pode ser dito sobre a complexidade da memória.
fonte
APL (Dyalog) , 20 bytes
Experimente online!
2⍴¯1
um negativo r eshaped em uma lista de comprimento dois⎕,
obter entrada (mnemonic: console box) e preceder a essan←
armazenar isso em n,\
prefixos de n (lit. concatenação cumulativa)(
…)¨
Aplique a seguinte função tácita a cada prefixo,
[é] a viagem (apenas garante que o prefixo seja uma lista)≢
diferente de∪
os elementos únicos [?] (ou seja, o prefixo tem duplicatas?)n/⍨
use isso para filtrar n (remove todos os elementos até o primeiro para o qual uma duplicata foi encontrada)⊃
escolha o primeiro elemento dessefonte
APL (Dyalog) , 11 bytes
De acordo com as novas regras , gera um erro se não houver duplicatas.
Experimente online!
⍳⍨
os índices da primeira ocorrência de cada elemento~
removido de⍳∘≢
de todos os índices⍬⍴
remodelar isso em um escalar (dá zero se nenhum dado estiver disponível)⊃⍨
use isso para escolher (dá erro zero)⊢
o argumentofonte
APL, 15
Parece que podemos retornar 0 em vez de -1 quando não houver duplicatas (obrigado Adám pelo comentário). Então, 3 bytes a menos.
Um pouco de descrição:
Para referência, a solução antiga adicionou -1 à lista no final; portanto, se a lista acabar vazia, ela conteria -1 e o primeiro elemento seria -1.
Experimente em tryapl.org
fonte
¯1
, o que{⊃⍵[(⍳⍴⍵)~⍵⍳⍵]}
deve acontecer.Retina ,
2624 bytesExperimente online! Explicação:
\b(\d+)\b
corresponde a cada número por vez e, a seguir, olha para trás para ver se o número é uma duplicata; se for a primeira1
partida, é!
emitido, em vez da contagem de partidas. Infelizmente, colocar o lookbehind em primeiro lugar não parece funcionar, caso contrário, ele salvaria vários bytes. Edit:Adicionado 7 bytes para cumprir com oEconomizou 2 bytes graças a @MartinEnder.-1
valor de retorno em nenhuma correspondência.fonte
-1
.MATL , 8 bytes
Dá um erro (sem saída) se não existir duplicado.
Experimente o MATL Online!
Explicação
fonte
R, 34 bytes
Corte alguns caracteres da resposta de @djhurio, mas não tenha reputação suficiente para comentar.
fonte
-1
mas com a nova especificação, consegui reduzir ainda mais. Isso ainda é sólido e é uma abordagem diferente da maneira como ele fez isso, então eu vou te dar um +1!J,
1716 bytesQuão?
fonte
R , 28 bytes
Experimente online!
fonte
NA
para valores ausentes, pois a especificação mudou; então(x=scan())[duplicated(x)][1]
é perfeitamente válido.J , 12 bytes
Experimente online!
Explicação
fonte
Dyalog APL Classic, 18 caracteres
Só funciona em
⎕IO←0
.Remova da lista de índices dos elementos do argumento com um "-1" anexado os índices da lista de seu nub e, em seguida, escolha o primeiro que resta. Se após a remoção restar apenas um vetor vazio, seu primeiro elemento será por definição 0, que é usado para indexar o argumento estendido produzindo o -1 desejado.
fonte
¯1
, para remover¯1,
e usar⎕IO←1
.Ruby ,
2836 bytesMal entendeu o desafio pela primeira vez.
O(n)
tempo,O(n)
espaço.Experimente online!
fonte
Java (OpenJDK 8) ,
65117109 bytesSolução anterior de 65 bytes:
Nova solução. 19 bytes são incluídos para
import java.math.*;
-8 bytes graças a @Nevay
Experimente online!
Editar
O algoritmo no meu programa original estava bom, mas o tamanho estático do tipo de dados usado significava que ele quebrou rapidamente quando o tamanho ficou acima de um certo limite.
Alterei o tipo de dados usado no cálculo para aumentar o limite de memória do programa para acomodar isso (usando
BigInteger
precisão arbitrária em vez deint
oulong
). No entanto, isso torna discutível se isso conta ou não comoO(1)
complexidade de espaço.Deixarei intacta minha explicação abaixo, mas desejo acrescentar que agora acredito que é impossível alcançar a
O(1)
complexidade do espaço sem fazer algumas suposições.Prova
Defina
N
como um número inteiro tal que2 <= N
.Let
S
Ser uma lista representando uma série de números inteiros aleatórios[x{1}, ..., x{N}]
, ondex{i}
tem a restrição1 <= x{i} <= N
.A complexidade do tempo (na notação Big-O) necessária para percorrer esta lista exatamente uma vez por elemento é
O(n)
O desafio dado é encontrar o primeiro valor duplicado na lista. Mais especificamente, estamos pesquisando o primeiro valor em
S
que é uma duplicata de um item anterior na lista.Seja
p
eq
seja a posição de dois elementos na lista, tais quep < q
ex{p} == x{q}
. Nosso desafio passa a ser encontrar o menorq
que satisfaça essas condições.A abordagem óbvia para esse problema é iterar através de S e verificar se
x{i}
existe em outra listaT
: sex{i}
não existirT
, armazenamosT
. Sex{i}
existeT
, é o primeiro valor duplicado e, portanto, o menorq
, e, como tal, o retornamos. Essa eficiência de espaço éO(n)
.Para alcançar a
O(1)
complexidade do espaço e, ao mesmoO(n)
tempo, manter a complexidade do tempo, precisamos armazenar informações exclusivas sobre cada objeto da lista em uma quantidade finita de espaço. Por esse motivo, a única maneira de qualquer algoritmo executar emO(1)
a complexidade do espaço é se: 1. N recebe um limite superior correspondente à memória necessária para armazenar o número máximo de valores possíveis para um tipo de dados finito específico. 2. A reatribuição de uma única variável imutável não é contada de acordo com a complexidade, apenas o número de variáveis (uma lista sendo várias variáveis). 3. (Com base em outras respostas) A lista é (ou pelo menos os elementos da lista são) mutáveis e o tipo de dados da lista é predefinido como um número inteiro assinado, permitindo que alterações sejam feitas nos elementos adicionais da lista sem usar memória adicional.1 e 3 exigem suposições e especificações sobre o tipo de dados, enquanto 2 exige que apenas o número de variáveis seja considerado para o cálculo da complexidade do espaço, em vez do tamanho dessas variáveis. Se nenhuma dessas suposições for aceita, seria impossível obter
O(n)
complexidade de tempo eO(1)
complexidade de espaço.Explicação
Uau, rapaz, este levou
um tempo embaraçosamente longo para pensarum pouco no poder do cérebro.Então, pegar o bônus é difícil. Precisamos operar sobre a lista inteira exatamente uma vez e rastrear quais valores já foram repetidos sem complexidade adicional de espaço.
A manipulação de bits resolve esses problemas. Inicializamos nosso
O(1)
'armazenamento', um par de números inteiros, depois percorremos a lista, OU inserindo o i-ésimo bit em nosso primeiro número inteiro e armazenando o resultado no segundo.Por exemplo, se temos
1101
e realizamos uma operação OR10
, obtemos1111
. Se fizermos outra sala de cirurgia10
, ainda temos1101
.Logo, quando realizamos a operação OR e terminamos com o mesmo número, encontramos nossa duplicata. Nenhuma duplicata na matriz faz com que o programa atropele e lance uma exceção.
fonte
PHP,
56 44 3832 bytesExecute assim:
Explicação
Tweaks
Complexidade
Como pode ser visto na versão comentada do código, a complexidade do tempo é linear
O(n)
. Em termos de memória, um máximo den+1
variáveis será atribuído. Então é issoO(n)
.fonte
error_reporting
opção à contagem de bytes (ou usar-n
, que é gratuito)./dev/null
, o que é o mesmo.O(1)
para espaço adicional? Você está atribuindo literalmente um novo per variáveln
, que éO(n)
Java 8,
827876 bytesNão é mais viável,756764 bytes abaixo na ediçãoComo uma função lambda:
Provavelmente pode ser feito muito menor, isso foi muito rápido.
Explicação:
*Editar*
756764 bytes usando a estratégia de negação:Experimente online!
(-3 bytes graças a @Nevay)
Explicação:
Loops sobre a matriz, negando manter o controle. Se não houver enganos, apenas atropele e gera um erro.
Ambos trabalham com O (n) tempo e O (n) complexidade do espaço.
fonte
Number
, poisi
é umlong
e-1
é umaint
.long
, mas não noLong
necessário, para que o lambda seja atribuído a umFunction
. Você testou? Independentemente disso, essa solução pode ser substituída pela sua nova.Set s=new HashSet();
para economizar 7 bytes. (Além disso: após a importação dejava.util.*;
, deve ser incluída na contagem de bytes -> +19 bytes.) A instrução return pode serreturn++j
, a instrução if pode ser removidaa->{int i=0,j;for(;(a[j=Math.abs(a[i++])-1]*=-1)<0;);return++j;}
(-3 bytes).Braquilog , 5 bytes
Experimente online!
Explicação
O adfix interno
a
lista primeiro todos os prefixos em ordem crescente de comprimento e, em seguida, sufixos em ordem decrescente de comprimento. Assim, a saída é produzida pelo prefixo mais curto que permite, se houver. Se um prefixo não tiver duplicatas, o restante do programa falhará, pois todas as subsequências de elementos iguais têm comprimento 1 e o primeiro elemento de sua cauda não existe. Se um prefixo tiver um elemento repetido, podemos escolher a subsequência comprimento-2 que contém ambos, e o programa retornará o último.fonte
a⊇Ċ=h
que analisa apenas os subconjuntos de comprimento-2.C #, 145 bytes
Provavelmente uma maneira muito mais curta de fazer isso em C # com um loop simples, mas eu queria tentar com o Linq.
Experimente online!
Versão completa / formatada:
fonte
Haskell ,
7869 bytesExperimente online!
Guardado 9 bytes graças a @nimi
Um caminho básico através da lista. Se o elemento atual ainda não foi visto (
i<0
) e está na lista de acumuladores (elem x a
), armazene o índice atual. Senão, mantenha o índice -1. De qualquer forma, adicione o elemento atual à lista do acumulador.Edição : Eu não li a pergunta com atenção suficiente: este código gera o índice do segundo elemento de um elemento duplicado.
fonte
\ ... ->(last$i:[j|i<0,elem x a],x:a)
. Além disso: não há necessidade def=
, porque funções sem nome são permitidas.Python 2,
7165 bytesDevoluções
None
se não houver elemento duplicadoEdit: -6 bytes graças a @ musicman523
Experimente online!
O (n) complexidade do tempo, O (n) complexidade do espaço, O (1) espaço auxiliar.
Como a lista de entrada usa espaço O (n) , a complexidade do espaço é limitada por isso. O que significa que não podemos ter uma complexidade de espaço menor que O (n)
Modifica a lista original, se isso não for permitido, poderíamos fazê-lo na mesma complexidade com 129 bytes
Explicação
Como todo elemento é maior que 0 e menor ou igual ao tamanho da lista, a lista possui para cada elemento a, um elemento no índice a - 1 (0 indexado). Exploramos isso dizendo que, se o elemento no índice i é negativo, já o vimos antes.
Para cada elemento a na lista n, deixamos que seja negativo o valor absoluto de a. (Deixamos que seja negativo, já que o python pode indexar listas com índices negativos, e seria necessário fazê-lo
u=abs(a)-1
) Se o elemento no índice u da lista for negativo, já o vimos antes e, portanto, podemos retornar -u (para obter o valor absoluto de a, pois todos os elementos são positivos) . Caso contrário, definimos o elemento no índice u como negativo, para lembrar que vimos um elemento de valor a antes.fonte
1
en
, como foi fornecida, obviamente não funcionará.Gelatina , 4 bytes
Experimente online!
Caso todos os elementos sejam únicos, isso retornará
0
(comportamento indefinido).fonte