65 votes

Trouver la ligne représentant le plus petit entier de la matrice triée par lignes

J'ai été a posé cette question dans un récent Java entretien téléphonique:

Vous êtes donné un NxN binaire (0-1) de la matrice avec les propriétés suivantes:

  • Chaque ligne est triée (de l'ordre de 0, suivie par la séquence de 1)
  • Chaque ligne représente un entier non signé (par la lecture des bits)
  • Chaque ligne est unique

Exemple:

0 1 1
1 1 1
0 0 1

Les valeurs des bits dans chaque ligne est triée et les lignes représentent les entiers 3, 7 et 1.

Trouver la ligne qui représente le plus petit entier. Dans l'exemple ci-dessus, la réponse est la ligne 3, qui représente le nombre entier 1.

J'ai commencé avec la force brute de complexité quadratique. L'interviewer a répondu en disant que je n'étais pas l'exploitation de la propriété sorted.

Après avoir réfléchi beaucoup, j'ai utilisé la recherche binaire sur chaque ligne et il est venu O(nlogn). Il m'a demandé si je pouvais l'améliorer davantage. J'ai beaucoup réfléchi, mais a échoué à améliorer.

Je vous serais reconnaissant si quelqu'un peut donner des pointeurs sur imporoving.

Un autre exemple:

0 1 1 1
0 0 0 1
0 0 0 0
1 1 1 1

La réponse sera la ligne 3, qui représente l'entier 0.

101voto

marcog Points 39356

Commencer avec la ligne 1. Allez à droite jusqu'à ce que vous frappez la première 1. Puis allez vers le bas à la ligne 2, mais restent dans la même colonne et répétez le processus d'aller à droite jusqu'à ce que vous frappez une 1. Faire cela à plusieurs reprises. La ligne dans lequel vous dernier en escalier droit est votre réponse.

C'est un O(N+M) solution (pour une matrice NxM, ou O(N) pour un carré de la matrice NxN, telle que donnée dans la question).

À l'aide de votre exemple de:

0 1 1 1
0 0 0 1
0 0 0 0
1 1 1 1

L' .'ici représentent le chemin parcouru:

. . 1 1
0 . . .
0 0 0 . . Last right step, therefore this is our answer
1 1 1 1 .

Cette solution fonctionne sur la non-carré matrices, tout en conservant un pire des cas O(N+M) l'efficacité d'une matrice NxM.

Pourquoi ce travail? La garantie que les numéros seront triés signifie que chaque ligne sera une série de 0 est suivi par une série de 1. De sorte que la grandeur d'une ligne est équivalent à la façon dont extrême droite, vous pouvez aller de l'avant de frapper un 1. Donc, si une ligne ne peut jamais vous aller plus loin en suivant simplement les de 0, alors il doit être plus que tout ce que nous avons traitées avant.

Le code Python:

li = [[0, 1, 1, 1],
      [0, 0, 0, 1],
      [0, 0, 0, 0],
      [1, 1, 1, 1]]

ans, j = 0, 0
for i, row in enumerate(li):
  while j < len(row) and row[j] == 0:
    j += 1
    ans = i

print "Row", ans+1, "".join(map(str, li[ans]))

Il y a aussi une solution plus simple, en raison de contraintes de toujours avoir un carré de la matrice NxN et les différentes lignes ensemble. Ensemble, ils signifient que la ligne avec la valeur la plus basse sera soit 0 0 ... 0 1 ou 0 0 ... 0 0. C'est parce qu'il y a N de N+1 nombres représentés dans la matrice, de sorte que le "manque" nombre est soit 0 (dans ce cas, la plus petite valeur représentée est de 1), ou c'est autre chose (la plus petite valeur est 0).

Avec cette connaissance, nous vérifions la deuxième colonne en partant de la droite pour un 0. Quand on trouve une, on regarde à sa droite, et qui contient un autre 0 nous avons notre réponse (il ne peut y avoir une ligne se terminant par un 0). Sinon, nous continuons à chercher de la colonne pour l'autre 0. Si nous ne trouvons pas autre 0, le premier que nous avons trouvé était la ligne que nous cherchez pour (il ne peut y avoir une ligne se terminant en 01 et puisqu'il n'y a aucune fin en 00, c'est la plus petite).

Le code Python:

li = [[0, 1, 1, 1],
      [0, 0, 0, 1],
      [0, 0, 0, 0],
      [1, 1, 1, 1]]

for i, row in enumerate(li):
  if row[-2] == 0:
    ans = i
    if row[-1] == 0:
      break

print "Row", ans+1, "".join(map(str, li[ans]))

Cette solution répond à la question avec moins de difficulté en O(N), mais la généralisation de gérer les non-carré NxM matrices ou non distinct numéros fera son pire des cas, l'efficacité de O(N^2). Personnellement, je préfère la première solution.

50voto

Itay Karo Points 10446

le nombre le plus faible doit être 0 ou 1. (parce qu'il y a pas de duplications et les lignes sont triées). tout ce que vous avez à faire est d'aller au cours de la dernière colonne, si ti contient 0 nombre le plus faible est 0 sinon nombre le plus faible est 1.

EDIT - explication
En N lignes avec la contrainte saturée il peut y avoir un maximum de N+1 des valeurs uniques.
donc, pour que au moins 0 ou 1 doivent être dans la matrice....

Edit 2 - algorithme

//assuming the matrix is 0 indexed base
for i = 0...N-1
  if M[i][N-1] == 0
    return "Value is 0 in row i";
for i = 0...N-1
  if M[i][N-2] == 0
    return "Value is 1 in row i";
//because of the explanation above the flow will never reach here.

40voto

Amey Points 1147

Étant donné que les numéros sont uniques et depuis, les chiffres sont triés, il est tout à fait clair que, pour toute valeur de N, le plus petit nombre peut être de la forme [0(N-1 fois), suivi par 1] ou 0(N fois).

Par exemple, pour N=4, le plus petit nombre peut être 0001 ou 0000.

En d'autres termes, deuxième du dernier chiffre du numéro nous souhaitons trouver doit être 0. Et le dernier chiffre peut être 0 ou 1

Ce problème alors réduit à seulement trouver ces modèles dans la matrice, ce qui peut être fait à l'aide d'une simple boucle for

int rowNum = -1;

for(int i=0;i<N;i++)
{
    if(arr[i][N-2]==0) //Second last digit is 0. Hence the number could be min.
    {
        rowNum = i;

        if(arr[i][N-1]==1) // If number of the form 0001 was found, keep looking for 0000
        {
            continue;
        }
        else
         //If number of the form 0000 was found, exit. 
         //No other number can be lesser than 0000
        {
            break;
        }
    }
}
return rowNum;

Cet algorithme aurait complexité O(n)

24voto

codaddict Points 154968

Vous souhaitez trouver un lignes avec le maximum de nombre de zéros.

  • Commencer à arr[0][0]
  • Si c'est 0, cochez l'élément vers à sa droite, arr[0][1].
  • Si ce n'est pas 0 puis de sauter la ligne et commencer à vérifier lors de l'élément dans la la ligne suivante en dessous de l'élément courant.

Continuer à le faire jusqu'à ce que vous allez passé la dernière ligne/dernière colonne ou vous trouver une ligne avec tous les zéros.

Algorithme:

i = 0 
j = 0 
answer = 0 

# continue till i is a valid index.
while(i<N) 

        # continue till j is valid index and ele is 0.
        while(j < N AND arr[i][j] == 0)

                # move towards right.
                j++ 

                #update answer.
                answer = i 

                # found a row with all zeros.
                if(j == N)  
                        break all loops.
                end-if

        end-while

        # skip current row..continue on next row.    
        i++ 

end-while

print answer

La complexité de ce est - O(N+N) qui O(N), qui est linéaire.

L'implémentation Java

Question connexe, Qui utilise exactement le même truc

Comment rechercher efficacement dans un ensemble ordonné de la matrice?

3voto

Paul Points 18124

Depuis les bits de chaque ligne sont triés, une fois que vous avez trouvé un bit à 1, tous les bits vers la droite doit être de 1 aussi. En d'autres termes, le tableau enregistre les valeurs de la forme 2^n-1.

Donc la réponse est la ligne la plus nulle des entrées est la plus petite.

Cependant, depuis seulement 2**m-1 entrées peuvent être présents, et il y a n de ceux-ci, et pas deux sont les mêmes, nous pouvons déduire plus - pour tout N il existe N+1, ces valeurs. Donc, soit 0 ou 1 doit être présent comme nous le savons, il n'y a pas de doublons.

Regardez donc pour une ligne vide (qui est le seul à colonne la plus à droite du zéro). Si vous ne le trouvez pas, la réponse est 1, sinon 0.

O(N)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X