240. Search two-dimensional matrix II

Keywords: less

An efficient algorithm is written to search a target value target in the m x n matrix. The matrix has the following characteristics:

The elements of each row are arranged in ascending order from left to right.
The elements of each column are arranged in ascending order from top to bottom.
Example:

The existing matrix is as follows:

[
[1, 4, 7, 11, 15],
[2, 5, 8, 12, 19],
[3, 6, 9, 16, 22],
[10, 13, 14, 17, 24],
[18, 21, 23, 26, 30]
]
Given target = 5, returns true.

Given target = 20, false is returned.

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        if(matrix.size()==0||matrix[0].size()==0){//A small pit, do not look at the last running array do not know, if the empty array, a run of the following code will cross the border!!!
            return false;
        }
        int row,col;
        row =matrix.size()-1;
        col =0;
        while(col<matrix[0].size()&&row>=0&&matrix[row][col]!=target){//Be sure to pay attention to the order. There must be cases that cross the boundary. It took me several times to get the order right
            if(matrix[row][col]>target){
                row--;
            }
            else{
                col++;
            }
        }
        if(col<matrix[0].size()&&row>=0)
            return true;
        else     
            return false;
    }
};

Method 1:

Because the rows and columns of the matrix are sorted (left to right and top to bottom, respectively), we can trim the O(m) or O(n) elements when looking at any particular value.

Algorithm:
First, we initialize a (row, col) pointer to the bottom left corner of the matrix. Then, until we find the target and return true (or the pointer points to (row, col) outside the matrix dimension), we do the following: if the current value is greater than the target value, we can "move up" one row. Otherwise, if the value currently pointed to is less than the target value, you can move a column. It's not hard to understand why this will never prune the correct answer; because rows are sorted from left to right, we know that each value to the right of the current value is larger. Therefore, if the current value is already greater than the target value, we know that each value to the right of it will be larger. A very similar argument can be made for columns, so this search will always find the target (if any) in the matrix.

class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
        // start our "pointer" in the bottom-left
        int row = matrix.length-1;
        int col = 0;

        while (row >= 0 && col < matrix[0].length) {
            if (matrix[row][col] > target) {
                row--;
            } else if (matrix[row][col] < target) {
                col++;
            } else { // found it
                return true;
            }
        }

        return false;
    }
}

//By LeetCode
//Link: https://leetcode-cn.com/problems/search-a-2d-matrix-ii/solution/sou-suo-er-wei-ju-zhen-ii-by-leetcode-2/
//Source: LeetCode
//The copyright belongs to the author. For commercial reprint, please contact the author for authorization. For non-commercial reprint, please indicate the source.

Complexity analysis

Time complexity: O(n+m).
The key to time complexity analysis is to notice that rows or columns are decremented / incremented exactly once per iteration (we do not return true). Since rows can only be reduced by m times, and columns can only be increased by n times, the loop cannot run more than n+m times before causing the while loop to terminate. Because all other work is constant, the total time complexity is linear in the sum of matrix dimensions.
Spatial complexity: O(1), because this method only deals with a few pointers, its memory usage is constant.

**

Method 2: search space reduction

**
We can divide the ordered two-dimensional matrix into four submatrixes, two of which may contain targets, and two of them certainly do not.

Algorithm:
Because the algorithm is recursive, its correctness can be judged by its basic situation and the correctness of recursive situation.

Basic information:
For ordered two-dimensional arrays, there are two methods to determine whether an arbitrary element target can be judged by a constant time. First, if the range of an array is zero, it does not contain elements and therefore cannot contain targets. Second, if the target is less than the minimum value of the array or greater than the maximum value of the array, then the matrix must not contain the target value.

Recursion:
If the target value is included in the array, so we follow the middle column of the matrix of the index row, matrix [row-1] [mid] < target < matrix [row] [mid], (obviously, if we find the target, we immediately return true). The existing matrix can be divided into four sub matrixes around this index; the upper left and right sub matrixes cannot contain the target (judged by the basic situation part), so we can delete them from the search space. In addition, the submatrix of the lower left corner and the upper right corner is a two-dimensional matrix, so we can apply this algorithm to them recursively.

class Solution {
    private int[][] matrix;
    private int target;

    private boolean searchRec(int left, int up, int right, int down) {
        // this submatrix has no height or no width.
        if (left > right || up > down) {
            return false;
        // `target` is already larger than the largest element or smaller
        // than the smallest element in this submatrix.
        } else if (target < matrix[up][left] || target > matrix[down][right]) {
            return false;
        }

        int mid = left + (right-left)/2;

        // Locate `row` such that matrix[row-1][mid] < target < matrix[row][mid]
        int row = up;
        while (row <= down && matrix[row][mid] <= target) {
            if (matrix[row][mid] == target) {
                return true;
            }
            row++;
        }

        return searchRec(left, row, mid-1, down) || searchRec(mid+1, up, right, row-1);
    }

    public boolean searchMatrix(int[][] mat, int targ) {
        // cache input values in object to avoid passing them unnecessarily
        // to `searchRec`
        matrix = mat;
        target = targ;

        // an empty matrix obviously does not contain `target`
        if (matrix == null || matrix.length == 0) {
            return false;
        }

        return searchRec(0, 0, matrix[0].length-1, matrix.length-1);
    }
}

//By LeetCode
//Link: https://leetcode-cn.com/problems/search-a-2d-matrix-ii/solution/sou-suo-er-wei-ju-zhen-ii-by-leetcode-2/
//Source: LeetCode
//The copyright belongs to the author. For commercial reprint, please contact the author for authorization. For non-commercial reprint, please indicate the source.
33 original articles published, praised 0, 488 visitors
Private letter follow

Posted by ferhanz on Mon, 24 Feb 2020 04:16:13 -0800