È possibile utilizzare questo semplice algoritmo che sfrutta il fatto che in una matrice con queste proprietà, un valore mtx[i][j]
è sempre più piccolo di qualsiasi valore mtx[x][y]
, dove x > i
o y > j
, in altre parole, qualsiasi valore a destra e giù:
public static boolean find(int[][] mtx, int val) {
int maxCol = mtx[0].length, minCol = 0;
for(int i = 0 ; i < mtx.length ; i++) {
for(int j = minCol ; j < maxCol ; j++) {
if(val == mtx[i][j]) return true;
if(val < mtx[i][j]) {
maxCol = j;
break;
}
}
if(maxCol == 0) break;
minCol = 0;
if(i != mtx.length-1 && val > mtx[i+1][maxCol-1]) minCol = maxCol-1;
}
return false;
}
L'idea è quella di cercare riga per riga, e se si trova un valore che è più grande, si può smettere di guardare in questa riga e si sa che non c'è bisogno di cercare al di là di quella colonna in righe future. E se il primo valore di una riga è più grande del valore, allora puoi smettere di cercare e restituire false. Inoltre, alla fine di ogni ricerca di riga, controlli la cella dalla riga successiva a maxCol-1
, se il valore è maggiore, quindi nel ciclo successivo, puoi saltare tutte le celle precedenti.
Lo scenario peggiore è il valore più grande (o più grande) e la complessità è O (m + n), perché verificherebbe tutta la prima riga, quindi salterà le successive m righe.
Immagino che si possa fare una ricerca binaria su ogni riga. Quello sarebbe O (m * log (n)). – marstran
Sì, questo è un miglioramento. – Zeus
Ogni riga è ridondante. Nota che in ogni sottotitolo, l'elemento in basso a destra è il massimo. Così, ad esempio, puoi attraversare la diagonale principale per trovare il primo valore V che è superiore al modello di ricerca. Il modello di ricerca deve risiedere da qualche parte nel complemento alla sottomatrice quadrata dall'angolo in alto a sinistra a V. – bipll