O que segue é o meu algoritmo para fazer isso no que acredito ser tempo e minha prova disso. Meu professor discorda que seja executado em e, em vez disso, pensa que é executado em Tempo. Quaisquer comentários sobre a prova em si ou o estilo (ou seja, minhas idéias podem ser claras, mas a apresentação não).
A pergunta original:
Dado números, encontre o maior entre eles a tempo . Você não pode assumir mais nada sobre.
Minha resposta:
- Classifique o primeiro elementos da matriz. Isso leva tempo, pois isso depende totalmente da , não .
- Armazene-os em uma lista vinculada (mantendo a ordem classificada). Isso também leva pelo mesmo motivo acima.
- Para todos os outros elementos da matriz, teste se é maior que o menor elemento da lista vinculada. Isso leva tempo como comparações devem ser feitas.
- Se o número for realmente maior, exclua o primeiro elemento da lista vinculada (a mais baixa) e insira o novo número no local que manteria a lista na ordem classificada. Isso leva tempo porque é limitado por uma constante () acima, pois a lista não cresce.
- Portanto, a complexidade total do algoritmo é .
Estou ciente de que o uso de uma árvore vermelho-preta em oposição à lista vinculada é mais eficiente em termos constantes (como o limite superior constante é em oposição a e o problema de manter um ponteiro para o elemento mais baixo da árvore (para facilitar as comparações) é eminentemente possível, simplesmente não me ocorreu na época.
Qual é a minha prova que está faltando? Existe uma maneira mais padrão de apresentá-lo (mesmo que esteja incorreto)?
Respostas:
Aqui está umO(n) algoritmo que resolve o problema.
Use o pior casoO(n) algoritmo de seleção para determinar an−m+1 estatísticas de terceira ordem. Deixeik seja esse número, que é o menor dos m maiores números que estamos tentando determinar.
Agora particione a matriz em torno do pivôk usando a partição QuickSort função de . Este passo levaO(n) também.
Saída dom números maiores: são dados por k e todos os números na sub-matriz superior gerados pela partição na etapa 2.
fonte
Seu algoritmo levaΘ(n+mn) Tempo. Eu suspeito que seu professor está procurando algo que levaO(n+nlogm) tempo, o que deve ser possível, talvez usando uma pilha ...
A fonte de sua discordância com o professor é que ele ou ela não parece pensarm é uma constante, apesar de como a pergunta está formulada. Se não for, entãoΘ(m) é muito pior que Θ(logm) .
fonte
Correçãom elementos encontrados até o momento em uma lista vinculada. Assim, no final do seu algoritmo, você testou todos os elementos e, portanto, possui o maiorm elementos na matriz. Seu algoritmo ainda está correto, mas declarar o objetivo da lista vinculada no início da descrição torna sua correção mais explícita.
Falta na sua apresentação é o loop invariável para estabelecer a correção: você mantém a maior
Tempo de execução
log10(10 billion)=10 , (na base 2, é aproximadamente ~ 33), o que é muito menor que 10 milhões. No exemplo dado,m é muitas vezes maior que logn e, portanto, não acho que você possa assumir com segurança que m é constante.
Você deve fornecer um algoritmo que sejao(nlogn) enquanto m=o(n) . Substituir sua lista vinculada e pesquisa linear por uma árvore de pesquisa binária equilibrada ou um min-heap alcançará este tempo de execução:O(mlogm+nlogm)=O(nlogm)=o(nlogn) . (assumindom=o(n) , caso contrário, seu tempo de execução é Θ(nlogn) )
Caso você não esteja familiarizado com a notação, a intuição por tráso(nlogn) é <O(nlogn) , mas consulte a pergunta correspondente em cs.SE para obter detalhes da notação.
fonte