题目

类型:二分查找
难度:中等
image.png

解题思路

方法一:两次二分查找

由于每行的第一个元素大于前一行的最后一个元素,且每行元素是升序的,所以每行的第一个元素大于前一行的第一个元素,因此矩阵第一列的元素是升序的。可以对矩阵的第一列的元素二分查找,找到最后一个不大于目标值的元素,然后在该元素所在行中二分查找目标值是否存在。

方法二:一次二分查找

将矩阵每一行拼接在上一行的末尾,则会得到一个升序数组,可以在该数组上二分找到目标元素。代码实现时,可以二分升序数组的下标,将其映射到原矩阵的行和列上。

代码

方法一:

  1. class Solution {
  2. public boolean searchMatrix(int[][] matrix, int target) {
  3. int rowIndex = binarySearchFirstColumn(matrix, target);
  4. if (rowIndex < 0) {
  5. return false;
  6. }
  7. return binarySearchRow(matrix[rowIndex], target);
  8. }
  9. public int binarySearchFirstColumn(int[][] matrix, int target) {
  10. int low = -1, high = matrix.length - 1;
  11. while (low < high) {
  12. int mid = (high - low + 1) / 2 + low;
  13. if (matrix[mid][0] <= target) {
  14. low = mid;
  15. } else {
  16. high = mid - 1;
  17. }
  18. }
  19. return low;
  20. }
  21. public boolean binarySearchRow(int[] row, int target) {
  22. int low = 0, high = row.length - 1;
  23. while (low <= high) {
  24. int mid = (high - low) / 2 + low;
  25. if (row[mid] == target) {
  26. return true;
  27. } else if (row[mid] > target) {
  28. high = mid - 1;
  29. } else {
  30. low = mid + 1;
  31. }
  32. }
  33. return false;
  34. }
  35. }

方法二:

class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
        int m = matrix.length, n = matrix[0].length;
        int low = 0, high = m * n - 1;
        while (low <= high) {
            int mid = (high - low) / 2 + low;
            int x = matrix[mid / n][mid % n];
            if (x < target) {
                low = mid + 1;
            } else if (x > target) {
                high = mid - 1;
            } else {
                return true;
            }
        }
        return false;
    }
}