Dado um std::vector
dos elementos distintos classificados em ordem crescente, quero desenvolver um algoritmo que determine se há dois elementos na coleção cuja soma é um determinado valor sum
,.
Eu tentei duas abordagens diferentes com suas respectivas vantagens e desvantagens:
Posso digitalizar o vetor inteiro e, para cada elemento do vetor, aplicar search binário (
std::lower_bound
) no vetor para pesquisar um elemento correspondente à diferença entresum
e o elemento atual. Esta é uma solução de tempo O (n log n) que não requer espaço adicional.Eu posso atravessar o vetor inteiro e preencher um
std::unordered_set
. Então, digitalizo o vetor e, para cada elemento, procurostd::unordered_set
a diferença entresum
e o elemento atual. Como a pesquisa em uma tabela de hash é executada em tempo constante, em média, essa solução é executada em tempo linear. No entanto, essa solução requer espaço linear adicional devido àstd::unordered_set
estrutura de dados.
No entanto, estou procurando uma solução que seja executada em tempo linear e não exija espaço linear adicional. Alguma ideia? Parece que sou forçado a trocar velocidade por espaço.
bem, como já recebemos uma matriz classificada, podemos fazê-lo com duas abordagens de ponteiro, primeiro mantemos um ponteiro esquerdo no início da matriz e um ponteiro direito no final da matriz e, em cada iteração, verificamos se a soma do valor de o índice do ponteiro esquerdo e o valor do índice do ponteiro direito são iguais ou não; se sim, retornam daqui; caso contrário, temos que decidir como reduzir o limite, ou seja, aumentar o ponteiro esquerdo ou diminuir o ponteiro direito; por isso, comparamos a soma temporária com dada soma e se essa soma temporária for maior que a soma especificada, decidimos reduzir o ponteiro direito; se aumentarmos o ponteiro esquerdo, a soma temporária permanecerá igual ou apenas aumentará, mas nunca menor, portanto, decidimos reduzir o ponteiro direito para que a soma temporária diminui e chegamos perto de nossa soma determinada, semelhante se a soma temporária for menor que a soma dada,portanto, nenhum significado de reduzir o ponteiro direito como soma temporária permanecerá soma ou diminuirá mais, mas nunca aumentará, portanto aumentamos nosso ponteiro esquerdo para que nossa soma temporária aumente e alcancemos a quantia próxima, e fazemos o mesmo processo repetidamente, a menos que obter a soma igual ou o valor do índice do ponteiro esquerdo se tornar maior que o índice do ponteiro direito ou vice-versa abaixo é o código para demonstração, deixe-me saber se algo não estiver clarodeixe-me saber se algo não está clarodeixe-me saber se algo não está claro
fonte