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

71 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

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

结果

执行结果:通过显示详情> 执行用时:17 ms ,在所有Java提交中击败了100.00%的用户 内存消耗:46.6 MB ,在所有Java提交中击败了99.35%的用户 通过测试用例:129/129

时间花费,心路历程

花费了一天,到晚上一点

思路

二分法,但是不能先行后列,应该按每行做二分

code

    public boolean findNumberIn2DArray(int[][] matrix, int target) {
        /**
         * 思路一:太难了,实现不出来
         * 使用深度搜索或者广度搜索,
         * 每个数字具有向右和向下两个方向的搜索
         * — 如果使用深度搜索,则采用栈的思路,一个方向上全部入栈,再出栈
         * — 如果使用广度搜索,则也是采用栈的思路,所有方向上全部入栈,再出栈
         * 同时,为了防止重复搜索,应该再设置一个等大的数组,如果访问了就设置为1,避免重复搜索。
         * — 为了节省空间,我们可以在原数组上直接设置一个标识数字,java强类型,好像做不到。那就设置成target。
         *   此时,只有向右或者向下匹配target的才算是真正的。
         * 如果遇到相同的数则返回True
         * 如果栈为空,则返回False
         *
         * 思路二:二分法 [实验证明,同时使用二分做不到,只能在每行使用二分或者每列使用二分]
         * 每次对半砍,在行和列两个维度上二分,和target做比较,判断在四块区域的哪一块
         * 特征就是左上第一个数的值永远是最小的,可以依据这个来判断
         * — 先按行方向走
         * — 再按列方向走
         */
        //判断是否为空
        if (matrix.length == 0 || matrix[0].length == 0) {
            return false;
        }
        for (int[] row : matrix) {
            //先按行方向走,确定列
            int rowLeft = 0;
            int rowRight = row.length - 1;
            int mid;
            while (rowLeft <= rowRight) {
                mid = (rowLeft + rowRight) / 2;
                System.out.println(rowLeft + "\t" + rowRight + "\t" + mid);
                if (row[mid] > target) {
                    //这里有-1
                    rowRight = mid - 1;
                } else if (row[mid] < target) {
                    //这里有加1
                    rowLeft = mid + 1;
                } else {
                    return true;
                }
            }
        }
​
        return false;
    }

\