Je veux commencer par dire que ce n'est PAS une question de devoirs. Je lis Introduction to Algorithms - le fameux texte CLRS pour devenir un meilleur programmeur. J'essaie de résoudre les problèmes et les exercices donnés dans le livre par moi-même.
J'essaie de résoudre Excercise 10.1-2 du chapitre 10 Structures de données élémentaires de CLRS Second Edition. Voici ce que ses états:
Expliquez comment implémenter deux piles dans un tableau A [1..n] de telle manière qu'aucune pile ne déborde à moins que le nombre total d'éléments dans les deux piles ensemble soit n . Les opérations PUSH et POP doivent s'exécuter en temps O (1) .
La solution que j'ai trouvée jusqu'à présent est la suivante:
Laissez le tableau A [1..n] implémenter deux piles: S1 [1..i] et S2 [i..n] .
Pour les opérations PUSH-S1 et PUSH-S2 , si la pile est `` pleine '', commencez à pousser les éléments dans l' autre pile (par exemple, si la pile S1 est pleine lorsqu'un nouvel élément essaie d'être inséré, puis poussez cet élément dans pile S2 et vice versa).
Le problème avec cette approche est que je ne pourrai pas POP-S1 ou POP-S2 de manière fiable car il n'y a aucun moyen de «se souvenir» de quel élément appartient à quelle pile. Si les éléments de la pile sont des paires (clé, valeur) , la clé étant le numéro de pile, alors pour faire apparaître un élément, je devrais rechercher, dans le pire des cas, i ou (ni) fois - qui sera O (n ) (n'hésitez pas à me corriger si je me trompe ici), ce qui ne serait pas O (1) .
Cela fait longtemps que je me tape la tête sur la question. Suis-je sur la bonne voie? Quelqu'un peut-il donner mes conseils possibles pour résoudre ce problème?
En général, comment dois-je «penser» à ces problèmes? Ou seulement des personnes vraiment intelligentes peuvent-elles résoudre ces types de problèmes? Est-ce que résoudre / résoudre des problèmes comme ceux-ci (c'est-à-dire acquérir de l'expérience) m'aidera à devenir meilleur dans ce domaine?
J'attends l'illumination.
la source
Réponses:
Un autre indice en plus de ce que Yuval a dit: il aide à placer les piles d'une manière spécifique dans les tableaux et à fixer leur direction de croissance en conséquence. Ils n'ont pas à grandir dans la même direction.
la source
Voici quelques conseils:
la source
La première pile commence à 1 et croît vers n, tandis que la seconde commence à partir de n et descend vers 1. Le débordement de pile se produit lorsqu'un élément est poussé lorsque les deux pointeurs de pile sont adjacents.
la source
Cette méthode utilise efficacement l'espace disponible. Il ne provoque pas de débordement s'il y a de l'espace disponible dans arr []. L'idée est de commencer deux piles à partir de deux coins extrêmes de arr []. stack1 commence à partir de l'élément le plus à gauche, le premier élément de stack1 est poussé à l'index 0. La stack2 commence à partir du coin le plus à droite, le premier élément de stack2 est poussé à l'index (n-1). Les deux piles croissent (ou rétrécissent) dans la direction opposée. Pour vérifier le débordement, tout ce que nous devons vérifier est l'espace entre les éléments supérieurs des deux piles.
la source
J'ai pensé à une autre solution. Si nous divisons le tableau en deux (ou aussi près que possible si le tableau a une longueur impaire) et faisons entrer le premier élément dans la première pile et le deuxième élément dans la deuxième pile. En sautant, nous pourrions revenir sur ces étapes. Cependant, en implémentant de cette manière cela violerait-il un principe de pile?
la source
Quelques conseils
Faire un tableau
Les éléments de tableau avec un indice impair sont pour stack1
Les éléments de tableau avec un index pair sont pour stack2
Vous pouvez maintenant agrandir les deux piles de gauche à droite
Gardez simplement les variables qui maintiennent la position supérieure des deux piles. Vous n'aurez pas à rechercher le tableau.
et si stack1 devient plein alors que stack2 est vide, vous pouvez garder une trace des éléments stack1 supplémentaires dans la stack2 en conservant certaines variables
la source