Ok, je suis fatigué car il est 3h du matin ici, mais j'ai un premier essai inplace avec exactement 2 passes sur chaque nombre dans la matrice, donc en O(NxN) et c'est linéaire dans la taille de la matrice.
J'utilise la première colonne et la première ligne comme marqueurs pour savoir où se trouvent les lignes/cols contenant uniquement des 1. Ensuite, il y a deux variables l et c pour se rappeler si la première ligne/colonne contient aussi des 1. Ainsi, la première passe définit les marqueurs et réinitialise le reste à 0.
La deuxième passe met 1 aux endroits où les lignes et les colonnes ont été marquées pour être 1, et remet à zéro la première ligne/col en fonction de l et c.
Je doute fortement que je puisse être fait en 1 passe car les carrés du début dépendent des carrés de la fin. Peut-être que ma 2ème passe peut être rendue plus efficace...
import pprint
m = [[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]]
N = len(m)
### pass 1
# 1 rst line/column
c = 1
for i in range(N):
c &= m[i][0]
l = 1
for i in range(1,N):
l &= m[0][i]
# other line/cols
# use line1, col1 to keep only those with 1
for i in range(1,N):
for j in range(1,N):
if m[i][j] == 0:
m[0][j] = 0
m[i][0] = 0
else:
m[i][j] = 0
### pass 2
# if line1 and col1 are ones: it is 1
for i in range(1,N):
for j in range(1,N):
if m[i][0] & m[0][j]:
m[i][j] = 1
# 1rst row and col: reset if 0
if l == 0:
for i in range(N):
m [i][0] = 0
if c == 0:
for j in range(1,N):
m [0][j] = 0
pprint.pprint(m)