2010-09-18 3 views
9

Étant donné une matrice N * N ayant 1s un 0 et un entier k, quelle est la meilleure méthode pour trouver une région rectangulaire de telle sorte qu'elle ait k 1 ???Rectangulaire dans un tableau

+0

Question intéressante. Cherchez-vous une seule région? Quelle est généralement la taille de N et k, et quelle est la distribution de probabilité de 1 et de 0? À quelle vitesse l'algorithme doit-il être? Je suppose que vous ne connaissez pas les réponses, parce que c'est une question d'entrevue, mais c'est ce que je demanderais. –

+0

Il est essentiel d'en savoir un peu plus. Si p est la probabilité de 1, et k/p est beaucoup plus petit que N, alors la méthode la plus simple consiste à essayer une seule ligne ou colonne. Prenez une région 1xk, comptez le nombre de ceux, puis ajoutez des cellules à la fin jusqu'à ce que vous en ayez k. Si k/p est beaucoup plus petit que N, cela a une forte probabilité de travailler. Bien sûr, si une rangée ne correspond pas aux exigences, vous pouvez passer à la suivante ... vous en avez N après tout. Mais qu'est-ce qui est «meilleur» de toute façon? Le pire des cas? Meilleur temps moyen? Le plus petit rectangle de résultat? – Joren

+1

Une question similaire est ici: http://stackoverflow.com/questions/1726632/dynamic-programming-largest-square-block – bobobobo

Répondre

2

Tenir compte de ce problème plus simple:

Étant donné un vecteur de taille N ne contenant que les valeurs 1 et 0, trouver une suite qui contient exactement les valeurs de k de 1 en elle.

Soit A le vecteur donné et S[i] = A[1] + A[2] + A[3] + ... + A[i], ce qui signifie combien de 1s il y a dans la sous-séquence A[1..i]. Pour chaque i, nous sommes intéressés par l'existence d'un j <= i tel que S[i] - S[j-1] == k.

Nous pouvons trouver dans O(n) avec une table de hachage en utilisant la relation suivante:

S[i] - S[j-1] == k => S[j-1] = S[i] - k

let H = an empty hash table 
for i = 1 to N do 
    if H.Contains (S[i] - k) then your sequence ends at i 
    else 
    H.Add(S[i]) 

Maintenant, nous pouvons l'utiliser pour résoudre votre problème donné dans O(N^3): pour chaque séquence de lignes dans votre matrice donnée (il y a O(N^2) séquences de lignes), considérez cette séquence pour représenter un vecteur et appliquer l'algorithme précédent. Le calcul de S est un peu plus difficile dans le cas de la matrice, mais ce n'est pas si difficile à comprendre. Faites-moi savoir si vous avez besoin de plus de détails.

Mise à jour: Voici comment l'algorithme fonctionnerait sur la matrice suivante, en supposant k = 12:

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

Tenir compte de la première ligne seule:

0 1 1 1 1 0 

Considérez-être le vecteur 0 1 1 1 1 0 et appliquez l'algorithme pour le problème le plus simple: nous trouvons qu'il n'y a pas de sous-séquence additionnant jusqu'à 12, donc nous passons à autre chose.

considérerons les deux premiers rangs:

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

Tenir compte qu'ils soient le vecteur 0+0 1+1 1+1 1+1 1+1 0+0 = 0 2 2 2 2 0 et appliquer l'algorithme pour le problème plus simple à ce sujet: encore une fois, pas qui ajoute séquence à 12, afin de progresser.

Tenir compte les trois premières lignes:

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

Tenir compte qu'ils soient le vecteur 0 3 3 3 3 0 et appliquer l'algorithme pour le problème plus simple là-dessus: on trouve la séquence de démarrage en position 2 et se terminant à la position 5 être la solution. De ceci nous pouvons obtenir le rectangle entier avec la comptabilité simple.

+0

Que voulez-vous dire par "séquence de lignes dans votre matrice donnée"? – yassin

+0

@Yassin Ezbakhe - Je veux dire une suite de rangées consécutives. Considérons une matrice qui a 5 lignes numérotées de 1 à 5. Les lignes 2, 3 et 4 forment une séquence de lignes. Traitez ces lignes comme un vecteur (les colonnes de ces lignes sont des éléments du vecteur) et appliquez l'algorithme pour le problème le plus simple. Comme il y a 'O (N^2)' telles suites de lignes et l'algorithme pour le problème plus simple est 'O (N)' et doit être appliqué sur toutes les séquences de lignes, la complexité totale de la solution est cubique. – IVlad

+0

Si vous avez la matrice [[0,1,1,1,1,0], [0,1,1,1,1,0], [0,1,1,1,1,0]], comment voulez-vous extraire le rectangle tout en 3x4? – yassin

3

Je peux le faire avec O (N^3 * log (N)), mais je suis sûr que la meilleure solution est plus rapide. D'abord vous créez une autre matrice N * N B (la matrice initiale est A). La logique de B est la suivante:

B[i][j] - is the number of ones on rectangle in A with corners (0,0) and (i,j). 

Vous pouvez évaluer B à O (N^2) par la programmation dynamique: B [i] [j] = B [i-1] [j] + B [ i] [j-1] - B [i-1] [j-1] + A [i] [j].

Maintenant, il est très facile de résoudre ce problème avec O (N^4) en itérant tout en bas à droite (i = 1..N, j = 1..N, O (N^2)), en bas à gauche (z = 1..j, O (N)), et en haut à droite (t = 1..i, O (N)) et vous obtenez le nombre d'unités dans ce rectangle à l'aide de B:

sum_of_ones = B[i][j] - B[i][z-1] - B[t-1][j] + B[t-1][z-1]. 

Si vous avez exactement k: k == sum_of_ones, alors vous obtenez le résultat. Pour le rendre N^3 * log (N), vous devriez trouver la recherche binaire droite-supérieure (ne pas simplement répéter toutes les cellules possibles).

Questions connexes