Search 2D Matrix

来源:互联网 发布:霸气业务网站源码 编辑:程序博客网 时间:2024/05/16 03:04
public class SearchA2DMatrix {    /*     * 方法 1:     *  对每一行使用二分法查找     * 每一行的时间复杂度为O(logN),将假设是M*N的矩阵,则时间复杂度为O(M*logN)     */    public boolean searchMatrix(int[][] matrix, int target) {        for (int i = 0; i < matrix.length; i++) {            if(binarySearch(matrix, i, target))                return true;        }        return false;    }    private boolean binarySearch(int[][] matrix, int row, int target) {        int start = 0;        int end   = matrix[row].length-1;        int mid   ;        while (start <= end) {            mid   = start + (end - start) / 2;            if(matrix[row][mid] == target)                return true;            if(matrix[row][mid] > target && matrix[row][start] <= target)                end = mid - 1;            else if(matrix[row][mid] < target && matrix[row][end] >= target)                start = mid + 1;            else                 return false;        }        return false;    }    /*     * 方法二:     *  Diagonal Binary Search     *  首先从左下角或右上角,例如从右上角matrix[0][m-1]进行搜索:     *      若matrix[0][m-1] < target,则排除第一行,在第2~n行进行搜索     *      若matrix[0][m-1] > target,则排除第m-1列,在第1~m-1列进行搜索     *      若matrix[0][m-1] = target,则找到,返回     *  时间复杂度为:O(M+N)     */    public boolean searchMatrix_02(int[][] matrix, int target) {        return searchHelper(matrix, 0, matrix[0].length-1, target);    }    private boolean searchHelper(int[][] matrix, int row, int col, int target) {        if(matrix[row][col] == target)            return true;        else if(matrix[row][col] > target && (col-1) >= 0) {            searchHelper(matrix, row, col-1, target);        }        else if(matrix[row][col] > target && (row+1) < matrix.length){            searchHelper(matrix, row+1, col, target);        }        return false;    }    //下面是其非递归写法    public boolean searchMatrix_02_2(int[][] matrix, int target) {        int row = 0;        int col = matrix[row].length - 1;        while(row < matrix.length && col >= 0) {            if(matrix[row][col] == target)                 return true;            else if(matrix[row][col] > target)                col--;            else                row++;        }        return false;    }    /*     * 方法3:采用分治算法(quadPart,四分)     *  将矩阵划分为四小块矩阵:     *      若中间的元素大于target, 则将左上角的矩阵排除从余下的三个矩阵中搜索     *      若中间的元素小于target,则将右下角的矩阵排除从余下的三个矩阵中搜索     *      若中间的严肃等于target,则返回true,搜索成功     * T(N) = 3*T(n/2) + C     * 计算的时间复杂度为:O(n^1.55)     */    public boolean searchMatrix_03(int[][] matrix, int target) {        return quadPart(matrix,target, 0, 0, matrix.length-1, matrix[0].length-1);    }    private boolean quadPart(int[][] matrix, int target, int x1, int y1, int x2, int y2) {        if(x1 > x2 || y1 > y2)            return false;        if(matrix[x1][y1] > target || matrix[x2][y2] < target)            return false;        int x = x1 + (x2 - x1) / 2;        int y = y1 + (y2 - y1) / 2;        if(matrix[x][y] == target)            return true;        else if(matrix[x][y] > target) {            return (quadPart(matrix, target, x1, y1, x-1, y-1) ||                    quadPart(matrix, target, x1, y, x-1, y2) ||                    quadPart(matrix, target, x, y1, x2, y-1));        }        else {            return (quadPart(matrix, target, x1, y+1, x, y2) ||                    quadPart(matrix, target, x+1, y1, x2, y) ||                    quadPart(matrix, target, x+1, y+1, x2, y2));        }    }    /*     * 方法4:Binary Partition     * 对于上面的方法不使用四分,通过合并将上面的三部分变成两部分     * 在中心所确定的行、列、对角进行搜索,然后对半分     * 在进行时间复杂度分析假设的是将矩阵等分,而编程时则不能这样考虑     * T(N) = 2*T(n/2)+cn     * 时间复杂度为:O(N*logN) < O(quadPart)     * 下面的实现是:     *  1. 通过在中间列上搜索满足条件: ai < s < ai+1,从而确定行数i+1,     *  2. 然后结果应该终止搜索时的确定的四个小矩阵的左下方和右上方的矩阵中搜索答案     */    public boolean  searchMatrix_04(int[][] matrix, int target) {        return binaryPartition(matrix, target, 0, 0, matrix.length-1, matrix[0].length-1);    }    private boolean binaryPartition(int[][] matrix, int target, int x1, int y1, int x2, int y2) {        if(x1 > x2 || y1 > y2)            return false;        if(matrix[x1][y1] > target || matrix[x2][y2] < target)            return false;        int midY = y1 + (y2 - y1) / 2;        int x    = x1;        while( x <= x2 && matrix[x][midY] <= target) {            if(matrix[x][midY] == target)                return true;            x++;        }        return (binaryPartition(matrix, target, x, y1, x2, midY-1)||                 binaryPartition(matrix, target, x1, midY +1, x-1, y2));    }       /*     *      * Binary Partition的改进:     *      因为搜索的行是有序的,因此通过折半的方法将搜索行的复杂度有O(N)变为O(logN)     *  因此有:     *      T(N) = 2*T(N/2) + clogN(假设是等分矩阵)     *      计算会可以得:      *      时间复杂度为:O(N)   不是最坏时间复杂度,事实上没有证明最坏时间复杂度是多少??     */}
0 0
原创粉丝点击