240. Search a 2D Matrix II 二维数组中的查找

Note:《剑指offer》面试题4,二维数组中的查找

解法一,超时O(m*n)

这种解法应该算是回溯法,但因为超时了,所以也不知道具体能不能通过所有testcase。
思路:有点像树的周游,当大于当前的数字,继续向下或是向右,如果相等返回,如果小于,返回上一级。用递归的方式进行查找。相比于解法三,这种方法浪费时间的地方在于,当前数字小于target时,它有两条可能的道路,回溯法有可能两条都需要尝试一下,而后者只有一个方向。

public boolean searchMatrix(int[][] matrix, int target) {
        if(matrix == null || matrix.length == 0 || matrix[0] == null || matrix[0].length == 0){
            return false;
        }
        return searchMatrix(matrix, 0, 0, target);

    }

    public boolean searchMatrix(int[][] matrix, int i, int j, int target) {
        // 超出范围
        if(i >= matrix.length || j >= matrix[0].length){
            return false;
        }

        // 比较
        int num = matrix[i][j];
        if(num == target){
            // 等于
            return true;
        }else if(num < target){
            // 小于,向下或是向右
            if(!searchMatrix(matrix, i+1, j, target)){
                return searchMatrix(matrix, i, j+1, target);
            }else{
                return true;
            }
        }else{
            // 大于,返回
            return false;
        }

    }

解法二,超时O(m*logn)

超时了,不知道是不是对的,只是算一种思路。
思路:因为每行都是排好序的,所以可以依次从第一行到最后一行都调用二分查找。这种方法相对于解法三,少考虑了列的规律。

    public boolean searchMatrix(int[][] matrix, int target) {
        if(matrix == null || matrix.length == 0 || matrix[0] == null || matrix[0].length == 0){
            return false;
        }

        int row = matrix.length;
        int col = matrix[0].length;
        for(int i = 0; i < row; i++){
            int start = 0;
            int end = col;
            int mid;
            while(end < col && end >=0 && start < col && start >= 0 && start <= end){
                mid = (end+start)/2;
                if(matrix[i][mid] < target){
                    start = mid+1;
                }else if(matrix[i][mid] > target){
                    end = mid-1;
                }else{
                    return true;
                }

            }
        }
        return false;
    }

解法三,O(m+n)

思路:从最后一列第一个数开始比较,如果大于则向下,如果小于则向左。为什么要这样做呢?可以把矩阵当做target可能的生存空间,当它从最后一列第一个数开始比较,如果target大于所在位置的数,那么这一行都小于target,target的生存空间将删除这一行,每次对比后的移动,都将删除它生存空间的一行或是一列,其实每次它都在和生存空间的最后一列的第一个数在进行比较。所以为什么大于只能向下不能向右,小于只能向左不能向上,因为它在之前的比较中已经排除了这些行列中。

public boolean searchMatrix(int[][] matrix, int target) {
        if(matrix == null || matrix.length < 1 || matrix[0].length <1) {
            return false;
        }
        int col = matrix[0].length-1;
        int row = 0;
        while(col >= 0 && row <= matrix.length-1) {
            if(target == matrix[row][col]) {
                return true;
            } else if(target < matrix[row][col]) {
                col--;
            } else if(target > matrix[row][col]) {
                row++;
            }
        }
        return false;
    }

你可能感兴趣的:(算法题)