思路:

从题中给出的有效信息有两点:

  • 每一行的数字都从左到右递增
  • 每一行的第一个数字都比上一行最后一个数字大

故此此矩阵是有序的,可以使用传统的二分查找进行取值。

方法一:两次二分查找

具体做法:
我们可以先通过二分查找确定 行,再对该 行 继续进行二分查找 ,思维较为常见,不做过多解读

import java.util.*;
public class Solution {
    /**
     * 
     * @param matrix int整型二维数组 
     * @param target int整型 
     * @return bool布尔型
     */
    public boolean searchMatrix (int[][] matrix, int target) {
        // write code here
        int N = matrix.length, M = matrix[0].length, left = 0, right = N - 1;
        while (left <= right) {
            int center = (right - left) / 2 + left;
            //比较每行的第一个元素
            if (matrix[center][0] == target) return true;  
            else if (matrix[center][0] < target) { 
                //center行的最后一个元素
                if (matrix[center][M - 1] == target) return true;  
                else if (matrix[center][M - 1] < target) left = center + 1;
                else if (matrix[center][M - 1] > target) { 
                    if (confirm(matrix[center], target)) return true;
                    else return false;
                }
            } else if (matrix[center][0] > target) {
                right = center - 1;
            }
        }
        return false;
    }
    private boolean confirm(int[] matrix, int target) {
        int N = matrix.length, left = 0, right = N - 1;
        while (left <= right) {
          int center = (right - left) / 2 + left;
          if (matrix[center] == target) return true;
          else if (matrix[center] < target) left = center + 1;
          else right = center - 1;
        }
        return false;
    }
}

复杂度分析:

  • 时间复杂度:O(logmn),其中 m是矩阵的行 和 n 是矩阵的列
  • 空间复杂度:O(1),原有数组上进行操作,未申请额外空间

方法二:一次二分查找

具体做法:
因为 每一行的第一个数字都比上一行最后一个数字大 ,所以我们可以通过 数学的方法 将其压缩为一个 一维矩阵 ,具体思路如下图所示
图片说明

import java.util.*;
public class Solution {
    /**
     * 
     * @param matrix int整型二维数组 
     * @param target int整型 
     * @return bool布尔型
     */
    public boolean searchMatrix (int[][] matrix, int target) {
        // write code here
        int M = matrix.length, N = matrix[0].length,left = 0, right = M * N - 1;
        while (left <= right) {
            int center = ( right - left) / 2 + left;
            int compute = matrix[center / N][center % N];
            if (compute < target) {
                left = center + 1;
            } else if (compute > target) {
                right = center - 1;
            } else {
                return true;
            }
        }
        return false;
    }
}

复杂度分析:

  • 时间复杂度:O(logmn),其中 m是矩阵的行 和 n 是矩阵的列
  • 空间复杂度:O(1),原有数组上进行操作,未申请额外空间