解题思路分析:整个矩阵的每一行以及每一列都是有序排列,那么找目标值可以使用二分查找方法。我的思路是先对每一行二分查找找到目标值的横坐标,在此横坐标所在的列进行二分查找,找到目标值的纵坐标。

代码如下:

class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
        // 横坐标二分查找
        int xIndex = -1;
        for(int i = 0; i < matrix.length; i++){
            int left = 0; 
            int right = matrix[i].length - 1;
            while(left <= right){
                int mid = left + (right - left) / 2;
                if(target > matrix[i][mid]){
                    left = mid + 1;
                }else if (target < matrix[i][mid]){
                    right = mid - 1;
                } else {
                    xIndex = mid;
                    break;
                }
            }
        }

        // 纵坐标二分查找
        int yIndex = -1;
        if(xIndex != -1){

            for(int i = 0; i < matrix.length; i++){
                int left = 0;
                int right = matrix.length - 1;
                while(left <= right){
                    int mid = left + (right - left) / 2;
                    if(target > matrix[i][xIndex]){
                        left = mid + 1;
                    }else if (target < matrix[i][xIndex]){
                        right = mid - 1;
                    }else {
                        yIndex = mid;
                        break;
                    }
                }
            }
        }
        
        if(xIndex != -1 && yIndex != -1){
            return true;
        }else{
            return false;
        }
    }
}

时间复杂度为 O(mlogn) + O(mlogm),简化为 O(mlogn)。

简化代码后,可以遍历每一行,对每一行进行二分查找,就不用再单独确认横纵坐标了,因为本题只要求返回 true 或 false。

代码如下:

class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
        for(int[] row : matrix){
            int index = search(row, target);
            if(index != -1){
                return true;
            }
        }
        return false;
    }

    public int search(int[] row, int target) {
        int left = 0;
        int right = row.length - 1;
        while(left <= right){
            int mid = left + (right - left) / 2;
            if(target > row[mid]){
                left = mid + 1;
            }else if(target < row[mid]){
                right = mid - 1;
            }else{
                return mid;
            }
        }
        return -1;
    }
}

时间复杂度为 O(mlogn)。

Categories:

Tags:

No responses yet

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注