剑指 Offer 04. 二维数组中的查找

题目链接:https://leetcode-cn.com/problems/er-wei-shu-zu-zhong-de-cha-zhao-lcof/

题意:在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

思路: 把矩阵分成四块,右下角块的所有元素都比左上角的块大,一般来说,每次都可以淘汰1/4的元素。
这样,每次都将大矩阵分为四块,将target不可能在的那块淘汰,对剩下的三块继续递归分块

复杂度: 用我的土方法分析,n * m个元素,每次留下3/4的元素,迭代x次后变成一个元素,得到答案,那么 n * m * (3/4)x = 1,
得到 x = log3/4(1/(n * m))。然后我就蒙蔽了,这特么怎么估算?到底是多少?官网题解给的最少复杂度是O(n + m),那干脆假设n == m,和官网复杂度比较一下
上图!
剑指 Offer 04. 二维数组中的查找_第1张图片
可以看到在n == m的情况下,超过40个元素这样递归就有优势了
(各位大佬要是发现我时间复杂度算错了提醒我一下)
结果:
剑指 Offer 04. 二维数组中的查找_第2张图片
代码:

class Solution {
    public boolean findNumberIn2DArray(int[][] matrix, int target) {
        if(matrix == null || matrix.length == 0){
            return false;
        }
        return findNumberIn2DArray(matrix, target, 0, 0, matrix.length - 1, matrix[0].length - 1);
    }
    private boolean findNumberIn2DArray(int[][] matrix, int target, int x1, int y1, int x2, int y2){
        if(x1 >= matrix.length || 
        x2 >= matrix.length ||
        y1>= matrix[0].length || 
        y2 >= matrix[0].length ||
        target < matrix[x1][y1] || 
        target > matrix[x2][y2]){
            return false;
        }
        if(target == matrix[x1][y1]){
            return true;
        }
        int midx = (x1 + x2) / 2;
        int midy = (y1 + y2) / 2;
        return findNumberIn2DArray(matrix, target, x1, y1, midx, midy) ||
        findNumberIn2DArray(matrix, target, x1, midy + 1, midx, y2) ||
        findNumberIn2DArray(matrix, target, midx + 1, y1, x2, midy) ||
        findNumberIn2DArray(matrix, target, midx + 1, midy + 1, x2, y2);
    }
}

你可能感兴趣的:(dfs)