Można w ten prosty algorytm, który wykorzystuje fakt, że w matrycy z tych właściwości, wartość mtx[i][j]
jest zawsze mniejsza niż wartość mtx[x][y]
, gdzie x > i
lub y > j
, innymi słowy, każda wartość w prawo i dół:
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;
}
Chodzi o to, aby szukać wiersz po wierszu, a jeśli okaże się, że wartość jest większa, można przestać patrzeć w tym samym wierszu i wiesz, że nie trzeba szukać poza tym w kolumnie przyszłe rzędy. A jeśli pierwsza wartość wiersza jest większa niż wartość, możesz zatrzymać wyszukiwanie i zwrócić fałsz. Ponadto, na końcu wyszukiwania każdego wiersza, sprawdzasz komórkę od następnego wiersza pod maxCol-1
, jeśli wartość jest większa, to w następnym cyklu możesz pominąć każdą poprzednią komórkę.
Najgorszy scenariusz to największa wartość (lub większa), a złożoność to O (m + n), ponieważ sprawdziłaby cały pierwszy wiersz, a następnie pominie następne m wierszy.
Sądzę, że można wykonać wyszukiwanie binarne w każdym rzędzie. Będzie to O (m * log (n)). – marstran
To jest poprawa. – Zeus
Każdy wiersz jest zbędny. Zauważ, że w każdej submacie, dolny prawy element jest maksymalny. W ten sposób można na przykład przemieścić główną przekątną, aby znaleźć pierwszą wartość V wyższą niż wzorzec wyszukiwania. Wzorzec wyszukiwania powinien znajdować się gdzieś w uzupełnieniu do kwadratowej submatrix od lewego górnego rogu do V. – bipll