publicbooleansearchMatrix(int[][] matrix, int target){ if (matrix == null || matrix.length == 0 || matrix[0].length == 0) { returnfalse; } int row = matrix.length; int col = matrix[0].length; for (int r = 0; r < row; ++r) { for (int c = 0; c < col; ++c) { if (matrix[r][c] == target) { returntrue; } } } returnfalse; }
Time: $O(MN)$ Space: $O(1)$
Binary Search
Iterate over elements along the diagonal, and each time perform binary search horizontally and vertically.
publicbooleansearchMatrix(int[][] matrix, int target){ if (matrix == null || matrix.length == 0 || matrix[0].length == 0) { returnfalse; } int row = matrix.length, col = matrix[0].length; int r = 0, c = 0; while (r < row && c < col) { // min(M, N) if (bsHelper(matrix, r, c, target)) returntrue; r += 1; c += 1; } returnfalse; }
privatebooleanbsHelper(int[][] matrix, int r, int c, int target){ int row = matrix.length; int col = matrix[0].length; if (r >= row || c >= col) { returnfalse; } // horizontal int lo = c, hi = col - 1; while (lo <= hi) { int mid = lo + (hi - lo) / 2; if (matrix[r][mid] == target) returntrue; if (matrix[r][mid] > target) { hi = mid - 1; } else { lo = mid + 1; } } // vertical lo = r; hi = row - 1; // semicolon while (lo <= hi) { int mid = lo + (hi - lo) / 2; if (matrix[mid][c] == target) returntrue; if (matrix[mid][c] > target) { hi = mid - 1; } else { lo = mid + 1; } } returnfalse; }
Time: $O(N\log{M})$ or $O(M\log{N})$ Space: $O(1)$
Search Space Reduction
Start from the corner up-right or bottom-left.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
publicbooleansearchMatrix(int[][] matrix, int target){ if (matrix == null || matrix.length == 0 || matrix[0].length == 0) { returnfalse; } int row = matrix.length; int col = matrix[0].length; int r = 0, c = col - 1; while (r < row && c >= 0) { if (matrix[r][c] == target) returntrue; if (matrix[r][c] > target) { c -= 1; } else { r += 1; } } returnfalse; }
publicbooleansearchMatrix(int[][] matrix, int target){ if (matrix == null || matrix.length == 0 || matrix[0].length == 0) { returnfalse; } int row = matrix.length, col = matrix[0].length; return searchRect(matrix, target, 0, 0, col - 1, row - 1); }
privatebooleansearchRect(int[][] matrix, int target, int left, int up, int right, int down){ if (left > right || up > down) { returnfalse; // this submatrix has no height or no width } if (target < matrix[up][left] || target > matrix[down][right]) { returnfalse; // "target" is already larger than the largest or the smallest element } int mid = left + (right - left) / 2; // Locate "row" such that matrix[row - 1][mid] < target < matrix[row][mid] int row = up; while (row <= down && matrix[row][mid] <= target) { if (matrix[row][mid] == target) { returntrue; } row += 1; } return searchRect(matrix, target, left, row, mid - 1, down) || searchRect(matrix, target, mid + 1, up, right, row - 1); }