Como implementar duas pilhas em uma matriz?

15

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.

Suyash Gupta
fonte
3
"Lidar / resolver problemas como esses (ou seja, ganhar experiência) me ajudará a melhorar nisso?" Na minha experiência, esse é definitivamente o caso. Se nada mais, você terá pensado de várias maneiras sobre o problema e, somente com isso, desenvolverá mais insights. Como me disseram recentemente: a melhor maneira de ter boas idéias é ter muitas idéias.
G. Bach

Respostas:

7

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.

G. Bach
fonte
5

Aqui estão algumas dicas:

  1. Uma das pilhas deve crescer "para cima" e a outra "para baixo".
  2. Não há como 'lembrar' qual elemento pertence a qual pilha - você pode usar variáveis ​​adicionais para ajudá-lo com coisas assim. (Isso faz mais sentido com a solução proposta pela primeira dica.)
Yuval Filmus
fonte
1

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.

Pankaj Moolrajani
fonte
1

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.

MONU KUMAR
fonte
-1

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?

MindBrain
fonte
Bem-vindo à Ciência da Computação ! Infelizmente, sua proposta não funciona. Em uma matriz de comprimentoN, você deve poder armazenar duas pilhas que não excederão, a menos que o tamanho total exceda N (para poder lidar com uma pilha vazia e uma pilha de comprimentoN) Sua solução transborda se uma das pilhas excederN/2.
David Richerby
-2

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

user4129542
fonte
Isso é muito complicado. As respostas existentes já dão maneiras mais simples de resolver o problema
David Richerby