74. Search a 2D Matrix - Medium
Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties:
- Integers in each row are sorted from left to right.
- The first integer of each row is greater than the last integer of the previous row.
Example 1:
Input: matrix = [ [1, 3, 5, 7], [10, 11, 16, 20], [23, 30, 34, 50] ] target = 3 Output: true
Example 2:
Input: matrix = [ [1, 3, 5, 7], [10, 11, 16, 20], [23, 30, 34, 50] ] target = 13 Output: false
三刷:
use binary search once, map 2-dimensional coordinates into 1-d coordinates, r = mid / col, c = mid % col
time = O(log(mn)), space = O(1)
class Solution { public boolean searchMatrix(int[][] matrix, int target) { if(matrix == null || matrix.length == 0) { return false; } int m = matrix.length, n = matrix[0].length; int left = 0, right = m * n - 1; while(left <= right) { int mid = left + (right - left) / 2; int r = mid / n, c = mid % n; if(matrix[r][c] == target) { return true; } else if(matrix[r][c] > target) { right = mid - 1; } else { left = mid + 1; } } return false; } }
一刷:
M1: 用两次binary search,第一次先确定行,第二次在确定的这一行里查找
注意判断corner case!![], [[]] ...
通过bs找到top, down两个边界之后,判断一下target和top行最后一个数的大小关系:如果target比较大,那么在down中查找,反之在top中查找
确定了行tmp之后,同样通过bs找到l, r两个边界,判断l r 和target是否相等,如果两个都不相等,返回false
time: O(logM + logN) -- M, N: row, col of matrix , space: O(1)
class Solution { public boolean searchMatrix(int[][] matrix, int target) { if(matrix == null || matrix.length == 0 || matrix[0].length == 0) return false; int top = 0, down = matrix.length - 1; while(top + 1 < down) { int mid = top + (down - top) / 2; if(matrix[mid][0] == target) return true; if(matrix[mid][0] > target) down = mid; else top = mid; } int tmp = target > matrix[top][matrix[0].length - 1] ? down : top; int l = 0, r = matrix[0].length - 1; while(l + 1 < r) { int mid = l + (r - l) / 2; if(matrix[tmp][mid] == target) return true; if(matrix[tmp][mid] > target) r = mid; else l = mid + 1; } if(matrix[tmp][l] == target || matrix[tmp][r] == target) return true; return false; } }
二刷:
M1: 同上
class Solution { public boolean searchMatrix(int[][] matrix, int target) { if(matrix == null || matrix.length == 0 || matrix[0].length == 0) return false; int top = 0, down = matrix.length - 1; while(top + 1 < down) { int mid = top + (down - top) / 2; if(matrix[mid][0] == target) return true; else if(matrix[mid][0] > target) down = mid; else top = mid; } int row; if(target >= matrix[top][0] && target < matrix[down][0]) row = top; else if(target >= matrix[down][0] && target <= matrix[down][matrix[0].length - 1]) row = down; else return false; int left = 0, right = matrix[0].length - 1; while(left <= right) { int mid = left + (right - left) / 2; if(matrix[row][mid] == target) return true; else if(matrix[row][mid] > target) right = mid - 1; else left = mid + 1; } return false; } }
M2: 用一次binary search,把2d matrix想象成从0 ~ m * n - 1 的1d array,left = 0, right = m * n - 1, row = mid / n, col = mid % n
time: O(log(mn)), space: O(1)
class Solution { public boolean searchMatrix(int[][] matrix, int target) { if(matrix == null || matrix.length == 0) return false; int m = matrix.length, n = matrix[0].length; int left = 0, right = m * n - 1; while(left <= right) { int mid = left + (right - left) / 2; int r = mid / n, c = mid % n; if(matrix[r][c] == target) return true; else if(matrix[r][c] > target) right = mid - 1; else left = mid + 1; } return false; } }