Quero começar dizendo que essa NÃO é uma pergunta de lição de casa. Estou lendo Introdução aos algoritmos - o famoso texto do CLRS para se tornar um programador melhor. Estou tentando resolver os problemas e exercícios dados no livro sozinho.
Estou tentando resolver o Exercício 10.1-2 do Capítulo 10 Estruturas de dados elementares do CLRS Second Edition. Aqui está o que seus estados:
Explique como implementar duas pilhas em uma matriz A [1..n] de tal maneira que nenhuma pilha exceda o limite, a menos que o número total de elementos em ambas as pilhas juntos seja n . As operações PUSH e POP devem ser executadas no tempo O (1) .
A solução que eu encontrei até agora é:
Deixe o array A [1..n] implementar duas pilhas: S1 [1..i] e S2 [i..n] .
Para as operações PUSH-S1 e PUSH-S2 , se a pilha estiver 'cheia', comece a empurrar elementos para a outra pilha (por exemplo, se a pilha S1 estiver cheia quando um novo elemento estiver tentando ser pressionado, empurre-o para dentro pilha S2 e vice-versa).
O problema com essa abordagem é que não poderei POP-S1 ou POP-S2 de maneira confiável, pois não há como 'lembrar' qual elemento pertence a qual pilha. Se os elementos da pilha forem pares (chave, valor) , sendo a chave o número da pilha, para exibir um elemento, eu teria que pesquisar, no pior caso, i ou (ni) vezes - que será O (n ) (sinta-se à vontade para me corrigir se estiver errado aqui), o que não seria O (1) .
Eu tenho batido minha cabeça na pergunta por um bom tempo agora. Estou no caminho certo? Alguém pode dar meus possíveis ponteiros para resolver este problema?
Em geral, como devo 'pensar' sobre esses problemas? Ou apenas pessoas realmente inteligentes podem resolver esses tipos de problemas? Lidar com / resolver problemas como esses (isto é, ganhar experiência) me ajudará a melhorar nisso?
Aguardo a iluminação.
fonte
Respostas:
Outra dica, além do que Yuval disse: ajuda a colocar as pilhas de uma maneira específica nas matrizes e a fixar sua direção de crescimento de acordo. Eles não precisam crescer na mesma direção.
fonte
Aqui estão algumas dicas:
fonte
A primeira pilha começa em 1 e cresce em direção a n, enquanto a segunda começa em forma de n e cresce em direção a 1. O estouro de pilha acontece quando um elemento é pressionado quando os dois ponteiros da pilha são adjacentes.
fonte
Este método utiliza com eficiência o espaço disponível. Não causa um estouro se houver espaço disponível em arr []. A idéia é iniciar duas pilhas de dois cantos extremos de arr []. A pilha1 inicia no elemento mais à esquerda, o primeiro elemento na pilha1 é empurrado no índice 0. A pilha2 inicia no canto mais à direita, o primeiro elemento na pilha2 é empurrado no índice (n-1). Ambas as pilhas crescem (ou encolhem) na direção oposta. Para verificar o estouro, tudo o que precisamos verificar é o espaço entre os principais elementos das duas pilhas.
fonte
Pensei em outra solução. Se dividirmos a matriz pela metade (ou o mais próximo possível, se a matriz tiver um comprimento ímpar) e fazer com que o primeiro elemento entre na primeira pilha e o segundo elemento na segunda pilha. Enquanto popping, podemos refazer essas etapas. No entanto, ao implementar dessa maneira, isso violaria qualquer princípio de pilha?
fonte
Algumas dicas
Faça uma matriz
Elementos de matriz com índice ímpar são para stack1
Elementos de matriz com índice par são para stack2
Agora você pode aumentar as duas pilhas da direção esquerda para a direita
Apenas mantenha as variáveis que mantêm a posição superior das duas pilhas. Você não precisará pesquisar a matriz.
e se a pilha1 ficar cheia enquanto a pilha2 estiver vazia, você poderá acompanhar os elementos adicionais da pilha1 na pilha2, mantendo algumas variáveis
fonte