• 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;
        }
    }
  • 相关阅读:
    BZOJ3992 [SDOI2015]序列统计 【生成函数 + 多项式快速幂】
    BZOJ3993 [SDOI2015]星际战争 【二分 + 网络流】
    BZOJ3325 [Scoi2013]密码 【manacher】
    BZOJ3534 [Sdoi2014]重建 【矩阵树定理】
    BZOJ3507 [Cqoi2014]通配符匹配 【哈希 + 贪心】
    BZOJ2285 [SDOI2011]保密 【01分数规划 + 网络流】
    BZOJ4556 [Tjoi2016&Heoi2016]字符串 【后缀数组 + 主席树 + 二分 + ST表】
    BZOJ4817 [Sdoi2017]树点涂色 【LCT + 线段树】
    BZOJ1195 [HNOI2006]最短母串 【状压dp】
    malloc的使用、用malloc动态分配内存以适应用户的需求的源代码实例
  • 原文地址:https://www.cnblogs.com/fatttcat/p/10068886.html
Copyright © 2020-2023  润新知