74. Search a 2D Matrix

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;
    }
}
原文地址:https://www.cnblogs.com/fatttcat/p/10068886.html