Organiser 0 & amp; 1 dans un tableau
C'est une question d'entrevue que j'ai eue récemment. Je voudrais connaître les autres, de la perception de l'approche de ce problème.
Question:
Vous êtes donné une structure qui détient les informations sur les employés avec deux éléments, int
département et string
nom.
struct Employee
{
string Name;
int Dept;
}
Vous êtes donné les détails de N personnes, parmi lesquelles N/2 employés ont Dept == 0
et N/2 employés ont Dept == 1
aménagées dans un certains ordre arbitraire. Vous avez besoin de trier les détails de l'employé en fonction de leur Dept
valeur et il devrait être stable c'est à dire, de l'ordre de 1s et 0s dans le document original doit être maintenu.
Par exemple, étant donné les données d'exemple suivantes:
Nom Dept X1 0 X2 1 X3 0 X4 1 X5 0
après le tri, le résultat devrait être:
Nom Dept X2 1 X4 1 X1 0 X3 0 X5 0
L'algorithme doit être stable et la complexité du temps devrait être O(N), avec la constante de l'espace pour les autres variables (ce qui signifie que le tri doit être fait sur place).
source d'informationauteur
Vous devez vous connecter pour publier un commentaire.
Allouer un second tableau (O(N)). Itérer premier tableau et déplacer tous les 1 dans l'ordre où ils apparaissent pour la deuxième tableau. Itérer encore et déplacer le 0 qui sont à gauche, dans le même ordre pour la deuxième tableau. Toutes les opérations en O(N). Ce n'est PAS in situ (sur place) solution. Un non-stable in situ solution est obtenue par l'exécution du tri rapide de l'algorithme de partitionnement fois.
Après avoir effectué quelques recherches, il semble que la plus connue O(N) solutions sans aucune mémoire supplémentaire ne sont pas stables. Il est la recherche universitaire sur l'efficacité de 0-1 stable tri in situ (sur place), mais les solutions besoin de plus de mémoire. Je me demande si le premier énoncé du problème n'a pas été reproduit dans un exact de la mode. Sans exigence de stabilité, le problème est très facile; il est également facile sans in situ exigence. Avec à la FOIS des exigences (in situ, stable), la solution semble être insaisissable.
Parmi les réponses ici, il existe un algorithme qui fonctionne en temps O(N) et in situ, mais seulement si le champ clé est (1) mutables et (2) peut contenir un entier au lieu d'un seul bit. Cela fonctionne, mais n'est pas in situ 0-1 stable de tri, car il est supposé qu'il n'y est O(log N) en écriture de la mémoire disponible pour chaque élément du tableau.
Okey, voici ma démarche.
e.g a[] = { 1,0,0,0,1,1,1,0,0,1};
Pseudocode:
count1 = 0
etcount2 = (n/2)+1
De parcourir à travers le tableau,
À la fin de la traversée, vous avez de tableau rempli de chiffres de 0 à n-1 comme:
Maintenant, le problème vient de tri au-dessus de la résultante de tableau, ce qui peut être fait en O(N) comme ci-dessous:
Note: j boucle ne s'exécute que deux fois indépendamment sur " n " et a constante de la complexité. La commande de l'ensemble de cette boucle est de 2*n = O(n).
Après le tableau est trié, à Nouveau de parcourir à travers la matrice et de l'ensemble des éléments
arr[0]
àarr[n/2]
à'1'
etarr[(n/2)+1]
àarr[n]
comme'0'
.Espace complexité est constant et le temps de la complexité est O(etape 2) + O(etape 4) + O(etape 5) = n + 2n +n = 4*n = O(n).
à l'aide de
std::stable_partition
avecstd::equal_to
etstd::binder1st
devrait faire l'affaire dans une belle, fonctionnelle, STL comme:Bien sûr, cela suppose que les éléments du tableau ont certains de comparaison définie par l'opérateur (c'est à dire vous pouvez dire
array[i]==1
...). Si ils sont tout entiers, il n'aurait pas de sens de maintenir l'ordre ...De la complexité: pour être O(N)
stable_partition
a besoin de plus de mémoire. Si l'algorithme ne parvient pas à allouer de la mémoire supplémentaire, il effectue dans O(N log N).Utilisé ints au lieu de bits pour des raisons de simplicité, mais le concept sous-jacent est le même. Non pas que l'ordre les différentes 1s et 0s à la fin dans les questions!
Mis à jour pour les employés problème. Ajout d'un employé supplémentaire que la question initiale a dit qu'il y avait N/2 de chaque sorte, il y a un nombre pair, pour que ce soit vrai. Sinon, c'est la même chose.
Pas sûr que cette compile maintenant il faut le traiter comme le pseudo-code!
Le problème d'origine du texte de ne pas mentionner tous les autres champs à l'exception de l'entier (il a été modifié depuis).
Dans ce cas, la stabilité n'a pas de sens étant donné deux nombres égaux sont par ailleurs identiques. La solution est de simplement parcourir le tableau et mettre 1 n/2 fois et ensuite 0 n/2 fois.
Ce sera la première étape de tri radix.
En termes abstraits, vous pouvez utiliser une version modifiée de tri d'insertion, en remplaçant les valeurs zéro à droite, ainsi que toutes les valeurs de la gauche. Qui aurait une plus grande complexité de O(n), cependant.
Je suis un peu confus pourquoi la commande des questions, comme indiqué précédemment, les octets sont indiscernables.
EDIT: Le nouvel exemple aide. L'avantage de mon algorithme, même si c'est plus lent que le temps linéaire dans le pire des cas, c'est que c'est seulement O(n) dans l'utilisation de la mémoire. Puisque les uns et de zéros ne sont que des touches pour les gros objets (qui peuvent être arbitrairement grand), la mémoire peut être un sujet de préoccupation.
Ce que le diable, ici, c'est l'ensemble de la solution:
arr est la liste des éléments, point.l'id est 0 ou 1, stockées sous forme de int.
Ce code se déplace le 0s à l'avant.
Mon implémentation en Perl à l'aide de simples pondération.
La sortie de
<=>
etcmp
comparaisons est une valeur de-1,0,1
.En multipliant l'un des camparisons par deux nous obtenons un de
-2,0,2
.Après l'ajout de la valeur de l'autre opérateur, nous obtenons un de
-3,-2,-1,0,1,2,3
Je voulais voir comment de nombreuses comparaisons, il le ferait, j'ai ajouté quelques informations de débogage et est venu avec cette.
Voici une solution qui fonctionne pour un tableau de
int
. Vous pouvez le modifier.Il peut être fait en une seule passe et en place.
dernière position de l'élément.
le swap à la fois les éléments. En un seul passage, nous pouvons trier le tableau en O(n) fois.
Ex:
#include
#define N 6
int main()
{
int list[N]={1,1,0,0,0,0};
int s,fin,tmp;
s=0;fin=N-1;
Facile:
Et si vous voulez vraiment avoir la même 1s et 0s:
Voici mon (complet) coup de couteau à en C#. Il génère la liste et les bâtons aléatoire employés, afin de faire
numberOfEmployees
ce que vous voulez. Je me rends compte il y a probablement un moyen plus simple de le faire, parce que l'affiche originale spécifié qu'il y a une quantité égale de 0-dept employés 1-service des employés, mais je ne pouvais pas m'en empêcher.Je ne peux penser à un algorithme qui permettra de prendre en O(n + i) temps (dans le pire des cas O(2n-1) et dans le meilleur des cas O(n)) et pas d'espace supplémentaire. Nous commençons la traversée de la matrice de 0 à n-1 et à chaque fois que nous rencontrons un 1 on incrémente un compteur et les remplacer 1 par 0. Maintenant, quand nous avons atteint la fin du tableau, nous allons commencer à se déplacer vers l'arrière comme beaucoup de comptoir et d'initialiser chaque nombre avec 1.