Définir chaque cellule de la matrice à 0 si la ligne ou la colonne contient un 0
Donné une matrice NxN avec des 0 et des 1. Jeu de chaque ligne contient un 0
à tous 0
s et définissez chaque colonne qui contient une 0
à tous 0
s.
Par exemple
1 0 1 1 0
0 1 1 1 0
1 1 1 1 1
1 0 1 1 1
1 1 1 1 1
résultats dans
0 0 0 0 0
0 0 0 0 0
0 0 1 1 0
0 0 0 0 0
0 0 1 1 0
Microsoft Ingénieur m'a dit qu'il existe une solution qui n'implique pas de mémoire supplémentaire, à seulement deux variables booléennes et un laissez-passer, donc je suis à la recherche de cette réponse.
BTW, imaginez que c'est un peu de la matrice, donc juste 1s et 0s sont de permettre à l'être dans la matrice.
- Hein? Qu'est-ce que "chaque fois que vous rencontrez"? Dans quel ordre sont que vous rencontriez les éléments dans la matrice? Et si vous rencontrez tous les bits, ne sera pas vous obtenir tous les 0 de toute façon?
- Ainsi, l'ordre dans lequel vous décidez de rencontre éléments de la décision, la chose est que vous ne devez définir à 0 le bon éléments. Si vous rencontrez tous les bits mis à 0, oui la matrice va encore être rempli avec des zéros.
- Quels sont les "éléments nécessaires"? Êtes-vous donné deux matrices, l'une à la "source" de la matrice et une "cible" de la matrice, et vous devez décider de l'ordre dans lequel "la rencontre" les éléments de façon à obtenir la "cible" de la matrice?
- Donc, en d'autres termes, une cellule est de 1 ssi toutes les valeurs dans la ligne et la colonne sont 1 aussi?
- Qu'est ce que la question déclaré implique, mais ce n'est pas ce qui est prévu, parce que vous ne pouvez pas avoir tout 1 dans la matrice, sauf si c'est toutes les 1 du. 🙂
- Pour une valeur de 1 dans la matrice de toutes les valeurs dans sa ligne doivent également être de 1, et de toutes les valeurs, dans sa colonne doit également être 1. S'il y a des zéros sur sa ligne et de colonne, la valeur est zéro.
- Je pense que vous avez mal quelque chose pour le "1 pass' pense. Il peut être fait de façon linéaire en 2 passes, bien que sans la mémoire supplémentaire, à seulement 2 booléens 😉 Donc je suppose que c'est la solution qu'il voulait dire (voir ci-dessous)
- Pour "en passant par" la matrice, vous aurez besoin d'au moins une variable d'index (qui ne peut pas être de type boolean).
- Pouvez-vous s'il vous plaît double-vérifier avec votre ami si la description du problème est en effet correcte? Je pensais que je pouvais le faire avec les codes de Hamming ou des bits de parité, mais jusqu'à présent je n'ai eu aucun succès, et le problème tient à l'épinglage dans ma tête. 🙂
- Vous pouvez utiliser la matrice de la variable elle-même en tant que votre variable d'index. Suffit d'utiliser l'arithmétique des pointeurs de passer par la matrice.
- Je suis sûr que la solution a quelque chose à voir avec la récursivité. La bonne chose à propos de la récursivité est qu'il agit comme une machine à remonter le temps que si vous réglez votre cellule de matrice (dans ce cas) à la valeur de la fonction récursive, vous serez en mesure de le régler à une valeur que vous ne trouverez pas sur jusqu'à ce que l'avenir, vous permettant ainsi de remonter dans le temps, ce qui en fait vous pouvez faire cette chose en un seul passage. Aussi, vous pourrez faire votre indexation via les paramètres de la fonction récursive, plutôt que dans les boucles for.
- Idée intéressante : Son semblable, en théorie, à la résolution d'un soduku puzzle, juste avec le binaire 🙂
- Sonne comme montrant la domination de la 8-Reines, qui est un problème bien connu utilisé comme une référence dans AI +1
- geeksforgeeks.org/a-boolean-matrix-question
- non, si vous devez aller à travers l'élément une fois de plus pour vérifier sa valeur, c'est une deuxième passe.
Vous devez vous connecter pour publier un commentaire.
Ok, donc, je suis fatigué comme il est 3H du matin ici, mais j'ai d'abord essayer en place avec exactement 2 passes sur chaque nombre dans la matrice, donc en O(NxN) et il est linéaire en la taille de la matrice.
J'utilise la 1ère colonne et la première ligne en tant que marqueurs de savoir où sont rangées/colonnes avec seulement 1. Ensuite, il y a 2 variables l et de c à vous rappeler si la 1ère ligne/colonne sont tous les 1 aussi.
Ainsi, le premier passage ensembles de marqueurs et réinitialise le reste à 0.
La seconde passe jeux 1 dans les endroits où les lignes et les colonnes marquées à 1, et réinitialise la 1ère ligne/col en fonction de l et c.
Je doute fortement que j'ai peut être fait en 1 passe que des carrés dans le début dépendent de places à la fin. Peut-être mon 2ème passe peut être rendue plus efficace...
Cela ne peut pas être fait en une seule passe depuis un seul bit a un effet sur les bits avant et après dans n'importe quel ordre. OIE-ce que vous traversez le tableau, vous pouvez venir à travers un 0, ce qui signifie que vous devez revenir en arrière et modifier une précédente 1 à 0.
Mise à jour
De gens semblent penser que par la restriction de N pour certains à valeur fixe (disons 8) vous pouvez résoudre ce problème est un laissez-passer. Eh bien, c'est un) manque le point et b) ne sont pas à la question d'origine. Je n'aurais pas poster une question sur le tri et de s'attendre à une réponse qui a commencé ", en supposant que vous ne voulez trier les 8 choses...".
Cela dit, c'est une approche raisonnable si vous savez que ce N est en fait limitée à 8. Ma réponse ci-dessus répond à la question d'origine qui n'a pas de tels retriction.
Donc, mon idée est d'utiliser les valeurs dans la dernière rangée/colonne comme un drapeau pour indiquer si toutes les valeurs dans la colonne correspondante/ligne sont 1s.
À l'aide d'un Zig Zag scan à travers l'ensemble de la matrice à l'EXCEPTION de la dernière rangée/colonne. À chaque élément, vous définissez la valeur de la dernière rangée/colonne de la logique ET de lui-même avec la valeur de l'élément courant. En d'autres termes, si vous frappez un 0, la dernière rangée/colonne est définie à 0. Si vous avez un 1, la valeur de la dernière rangée/colonne 1 que si c'était le 1 déjà. En tout cas, réglez l'élément courant à 0.
Lorsque vous avez terminé, votre dernière rangée/colonne doit avoir 1 ssi le correspondant de la colonne/ligne a été rempli avec 1s.
Faire une analyse linéaire à travers la dernière rangée et de la colonne et de la recherche de 1s. Jeu de 1s dans les éléments correspondants dans le corps de la matrice où la dernière rangée et de colonne sont à la fois 1s.
De codage, il sera difficile d'éviter les hors-en-un, des erreurs, etc, mais il devrait fonctionner en un seul passage.
J'ai une solution ici, il s'exécute en un seul passage, et fait tout traitement "en place", sans plus de mémoire (enregistrer pour la culture de la pile).
Il utilise la récursivité pour retarder l'écriture de zéros qui bien sûr serait de détruire la matrice pour les autres lignes et colonnes:
Je ne pense pas que c'est faisable. Lorsque vous êtes sur la première place et sa valeur est 1, vous n'avez aucun moyen de savoir ce que les valeurs des autres places dans la même rangée et de colonne. Donc, vous avez pour vérifier celles et si il y a un zéro, revenir à la première place et changer sa valeur à zéro. Je vais vous recommandons de le faire en deux fois - la première passe rassemble des informations sur les lignes et les colonnes doivent être mis à zéro (les informations sont stockées dans un tableau, nous sommes donc à l'aide de certains de mémoire supplémentaire). La seconde passe de modifier les valeurs. Je sais que ce n'est pas la solution que vous cherchez, mais je pense que c'est une pratique. Les contraintes donné par vous rendre le problème insoluble.
Je peux le faire avec deux variables de type entier et deux passes (jusqu'à 32 lignes et de colonnes...)
~
inverse tous les bits d'une variable. 0x00000000 devient 0x00000000. En gros, j'ai commencer avec le tout, et efface le bit pour une ligne/colonne, lorsque j'ai trouvé un 0. CompleteCols a les bits 2 et 3 ensemble, et CompleteRows a les bits 2 et 4 set (0).le problème peut être résolu en un seul passage
économie de la matrice dans un i X j de la matrice.
maintenant imprimer toutes les valeurs à 0 pour les valeurs de i et j enregistré en a et b
reste des valeurs sont 1 ie (3,3) (3,4) (5,3) et (5,4)
Un autre solution qui prend deux passes, est d'accumuler de l'ANDs horizontalement et verticalement:
Je pensais que je pouvais concevoir un tel algorithme à l'aide de bits de parité, Les codes de Hamming ou la programmation dynamique, éventuellement à l'aide de ces deux booléens comme un 2-nombre de bits, mais je n'ai eu aucun succès.
Pouvez vous s'il vous plaît vérifier à nouveau l'énoncé du problème avec votre ingénieur du son et laissez-nous savoir? Si
il y est en effet une solution, je veux garder ébrèchent le problème.
Garder une seule variable pour garder une trace de ce que toutes les lignes ANDed sont ensemble.
Si une ligne est -1 (toutes les 1 s), puis de faire la ligne suivante, une référence à cette variable
Si une ligne est une chose mais, c'est un 0. Vous pouvez faire tout en un seul passage. Pseudo-code:
Qui devrait le faire, en un seul passage-mais il s'agit d'une hypothèse ici que N est assez petit pour le CPU pour faire de l'arithmétique sur une seule ligne, sinon vous allez avoir besoin de faire une boucle sur chaque ligne pour déterminer si c'est tous les 1 ou pas, je crois. Mais étant donné que vous demandez sur les algos et ne gênant pas mon matériel, je viens de commencer ma réponse à "Construire un CPU qui supporte à N bits de l'arithmétique..."
Voici un exemple de comment cela peut être fait en C. Remarque, je soutiens que les valeurs et l'arr pris ensemble représentent la matrice, et p et numproduct sont mes itérateur et ET produit des variables à utiliser pour implémenter le problème. (J'aurais pu en boucle sur arr avec l'arithmétique des pointeurs pour valider mon travail, mais une fois a suffit!)
Ce produit 0, 0, 6, 0, 6, qui est le résultat de la donnée d'intrants.
Ou en PHP, si les gens pensent que ma pile de jeux en C sont de la triche (je vous suggérer que ce n'est pas parce que je devrais être capable de stocker la matrice de n'importe quelle manière que je s'il vous plaît):
Suis-je raté quelque chose?
Beau challenge. Cette solution de tri de utilise seulement deux booléens créé sur la pile, mais les opérations booléennes sont créés plusieurs fois sur la pile puisque la fonction est récursive.
Ce scans dans un modèle du type:
et ainsi de suite
Et puis changeing les valeurs de ce modèle sur le retour sur chacune des fonctions de recherche. (Bottom-up):
et ainsi de suite
D'accord c'est une solution qui
En fait. Si vous voulez juste pour exécuter l'algorithme et d'imprimer les résultats (c'est à dire pas de les restaurer, puis cela peut facilement être fait en une seule passe. Le problème arrive lorsque vous essayez de modifier le tableau comme vous êtes en cours d'exécution de l'algorithme.
Voici ma solution, Elle consiste uniquement ANDing les lignes/colonnes de valeurs pour un givein (i,j)'s de l'élément et d'imprimer les documents.
J'ai essayé de résoudre ce problème en C#.
J'ai utilisé deux variables de boucle (i et j), à l'exception de la matrice et n représente sa dimension
Logique que j'ai essayé est de:
Code:
Alors que c'est impossible étant donné les contraintes, l'espace de la plupart de moyen efficace de le faire est par la traversée de la matrice dans une superposition, une alternance de lignes/colonnes de la mode, ce qui en ferait un modèle similaire à la pose des briques dans un zigzag de la mode:
En utilisant cela, vous allez dans chaque ligne/colonne, comme indiqué, et si vous rencontrez un 0 à tout moment, une variable booléenne, et re-marche de la ligne/colonne, la définition de la entrées à 0 comme vous allez.
Cela nécessitera pas de mémoire supplémentaire, et ne l'utiliser une variable booléenne. Malheureusement, si la "mesure" de bord est défini pour tous de 0, qui est le pire des cas, et vous marchez à l'ensemble de la baie à deux reprises.
créer une matrice de résultats et de définir toutes les valeurs de 1.
aller par le biais de la matrice de données dès qu'un 0 est rencontré, définir le résultat lignes de la matrice colonne à 0
À la fin de la première passe, le résultat de la matrice aura la bonne réponse.
A l'air assez simple. Est-il un truc que je suis absent? Vous n'êtes pas autorisé à utiliser un ensemble de résultats?
EDIT:
Ressemble à une fonction F#, mais c'est de la triche un peu car, même si vous faites un seul passage, la fonction peut être récursive.
Il ressemble à l'intervieweur est à essayer de comprendre si vous connaissez la programmation fonctionnelle.
Bien, je suis venu avec un seul passage, en place (non récursif) de la solution à l'aide de 4 booléens et 2 compteurs de boucles. Je n'ai pas réussi à le réduire à 2 booléens et 2 ints, mais je ne serais pas surpris si c'était possible. Il ne autour de 3 lectures et 3 écrit de chaque cellule, et il devrait être en O(N^2) ie. linéaire dans la taille de la matrice.
M'a fallu quelques heures pour puzzle de ça - je ne voudrais pas avoir à venir avec elle sous la pression d'une interview! Si j'ai fait une faire je suis trop fatigué pour le repérer...
Euh... j'ai opté pour définir "single-pass" que de faire un balayage à travers la matrice, plutôt que de toucher à chaque valeur une fois! 🙂
j'espère que vous apprécierez ma 1 passe-solution c#
vous pouvez récupérer un élément de O(1), et seulement besoin de
l'espace d'une ligne et d'une colonne de la matrice
1 passe, 2 booléens. Je viens d'avoir à assumer l'entier des indices dans les itérations ne comptent pas.
Ce n'est pas une solution complète, mais je ne peux pas me passer ce point.
Si seulement je pouvais déterminer si un 0 est un original 0 ou un 1, qui a été converti en 0 alors je ne voudrais pas avoir à utiliser de -1 et ce serait le travail.
Ma sortie ressemble à ceci:
L'originalité de mon approche est l'utilisation de la première moitié de l'examen d'une ligne ou d'une colonne afin de déterminer si elle contient un 0 et la dernière demi pour définir les valeurs - ce qui est fait en regardant x et de largeur x puis y et hauteur-y à chaque itération. Sur la base des résultats de la première moitié de l'itération, si un 0 dans la ligne ou la colonne a été trouvé, j'utilise la dernière moitié de l'itération pour modifier la 1 du 1 du.
Je viens de réaliser que cela pourrait être fait avec seulement 1 booléen en laissant 1 à ...?
Je poste ceci en espérant que quelqu'un pourrait dire, "Ah, il suffit de le faire..." (Et j'ai passé trop de temps de façon à ne pas publier.)
Voici le code en VB:
Personne n'est à l'aide de formes binaires? car c'est seulement de 1 et de 0. Nous pouvons utiliser des vecteurs binaires.
Voici le test:
Et la sortie:
Vous pouvez faire quelque chose comme cela d'utiliser un laissez-passer, mais une entrée et une sortie de la matrice:
où
col(xy)
est les bits de la colonne contenant le pointxy
;row(xy)
est les bits de la ligne contenant le pointxy
.n
est la taille de la matrice.Alors juste une boucle sur l'entrée. Éventuellement extensible à être plus efficace de l'espace?
Une matrice d'analyse, deux booléens, pas de récursivité.
Comment éviter le deuxième passage?
La seconde passe est nécessaire pour effacer les lignes ou les colonnes lorsque le zéro apparaît à la fin de leur activité.
Toutefois, ce problème peut être résolu, parce que lorsque l'on analyse la ligne #i nous savons déjà le statut de ligne pour la ligne #i-1. Ainsi, alors que nous sommes de la numérisation de la ligne #i nous pouvons simultanément claire la ligne #i-1 si c'est nécessaire.
La même solution fonctionne pour les colonnes, mais nous avons besoin de balayage des lignes et des colonnes simultanément alors que les données n'est pas modifié par l'itération suivante.
Deux booléens sont nécessaires pour stocker le statut de première ligne et la première colonne, parce que leurs valeurs seront modifiées lors de l'exécution de la partie principale de l'algorithme.
Pour éviter l'ajout de plus de booléens nous sommes le stockage de l' "clair" drapeau pour les lignes et les colonnes dans la première rangée et de colonne de la matrice.
semble que la suite fonctionne avec aucun espace supplémentaire requis:
d'abord noter que le fait de multiplier les éléments de la ligne fois les éléments de la ligne dans laquelle un élément est, donne la valeur souhaitée.
Afin de ne pas utiliser tout l'espace supplémentaire (pas de prendre une nouvelle matrice et de le remplir, mais au lieu d'appliquer les modifications de la matrice directement), commencer en haut à gauche de la matrice et de faire le calcul pour toute ixi de la matrice (qui "commence" à (0,0)) avant d'envisager n'importe quel élément avec un index > j'.
espère que cela fonctionne (havent testet)
C'est TESTÉ pour différentes N en C++, et est:
UN PASSAGE, DEUX BOOLÉENS, PAS DE RÉCURSIVITÉ, PAS DE MÉMOIRE SUPPLÉMENTAIRE, DÉTIENT POUR ARBITRARLY UN GRAND N
(Jusqu'à présent, aucune des solutions ne TOUTES ces.)
Plus spécifiquement, je suis amusant, deux compteurs de boucle sont d'accord. J'ai deux const unsigneds, qui n'existent que plutôt que d'être calculées à chaque fois pour des raisons de lisibilité. La boucle externe de l'intervalle [0, N], et la boucle interne de l'intervalle [1, n - 1]. L'instruction switch est dans la boucle pour la plupart montrent très clairement que c'est vraiment un passage.
Algorithme De Stratégie:
La première astuce est pour nous une ligne et d'une colonne de la matrice elle-même à accumuler le contenu de la matrice, cette mémoire devient disponible en déchargeant tout ce que nous vraiment besoin de savoir à partir de la première ligne et de la colonne en deux booléens. La deuxième astuce consiste à obtenir deux passes de l'un, à l'aide de la symétrie de la sous-matrice et de ses indices.
Algorithme Synopsis:
Templatized C++ Mise En Œuvre:
Ok, je me rends compte que ce n'est pas tout à fait un match, mais je l'ai eu en une seule passe à l'aide d'un booléen et un octet au lieu de deux booléens... à proximité. J'ai aussi ne pas se porter garant de l'efficacité, mais ces types de questions nécessitent souvent moins de solutions optimales.
Vous pouvez sorta de le faire en une seule passe, si vous ne comptez pas l'accès de la matrice d'accès aléatoire de l'ordre, ce qui élimine les avantages de le faire en une seule passe, en premier lieu (cache-cohérence/la mémoire de la bande passante).
[edit: simple, mais mauvaise solution supprimé]
Vous devriez obtenir une meilleure performance que tout seul passage par la méthode de le faire en deux passages: l'un à accumuler de la ligne/colonne d'infos, et un pour l'appliquer. Le tableau (en ligne ordre majeur) est accessible de façon cohérente, et pour les tableaux dépassement de la taille de la mémoire cache (mais dont les lignes peuvent tenir dans le cache), les données doivent être lues à partir de la mémoire deux fois, et stockés qu'une seule fois:
La solution la plus simple je pense est de collé ci-dessous. La logique est l'enregistrement en ligne et de la colonne de mise à zéro lors de l'itération.
Voici mon Ruby mise en œuvre avec le test inclus, Ce serait de prendre en O(MN) de l'espace. Si nous voulons une véritable mise à jour en temps (comme pour montrer les résultats lorsque nous découvrirons des zéros plutôt que d'attendre que la première boucle de trouver des zéros), il nous suffit de créer une autre variable de classe comme
@output
et chaque fois que nous trouvons un zéro à la mise à@output
et pas@input
.Le code ci-dessous crée une matrice de taille m,n. Déterminez d'abord les dimensions de la matrice. Je voulais remplir la matrice[m][n] avec au hasard avec des nombres entre 0..10. Créez ensuite une autre matrice de mêmes dimensions et de le remplir avec de l'-1s (finale de la matrice). Alors parcourir la matrice initiale pour voir si vous frapperez de 0. Lorsque vous appuyez sur position(x,y), aller à la finale de la matrice et de remplir la ligne x avec des 0 et la colonne y avec des 0.
À la fin de lecture par le biais de la finale de la matrice, si la valeur est -1 (valeur d'origine) copier la valeur dans le même endroit de la matrice initiale de finale.
voici ma solution. Comme vous pouvez le voir dans le code, donné une M * N de la matrice, il définit l'ensemble de la ligne de zéro une fois qu'il inspecte un zéro en ligne.la complexité du temps de ma solution est de O(M * N) .
Je partage l'ensemble de la classe qui a une statique peuplé de tableau pour le test et un affichage de la méthode de la baie pour voir le résultat dans la console.
}
Un Passe - j'ai traversé les saisies qu'une seule fois, mais utilisé un nouveau tableau et seulement deux variables Booléennes.
Définir un indicateur (un numéro qui est de contraindre j'utilise ici -1) puis une fois que nous changeons tous de ligne correspondante et le col , remplacer tous les drapeau à zéro