You can use this simple algorithm that exploits the fact that in a matrix with these properties, a value mtx[i][j]
is always smaller than any value mtx[x][y]
, where x > i
or y > j
, in other words, any value to the right and down:
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;
}
The idea is to search row by row, and if you find a value that is larger, you can stop looking in this row and you know that you don't have to search beyond that column in future rows. And if the first value of a row is bigger than the value, than you can stop searching and return false. Also, at the end of each row search, you check for the cell from the next row at maxCol-1
, if the value is larger, then in the next cycle, you can skip every cell preceding.
The worst case scenario is the largest value (or larger), and the complexity is O(m+n), because it would check all the first row, and then skip the next m rows.