第十六周_A-二维数组中的查找

91 阅读1分钟

题目

leetcode.cn/problems/er…

在一个 n * m 的二维数组中,每一行都按照从左到右 非递减 的顺序排序,每一列都按照从上到下 非递减 的顺序排序。

请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

示例:

现有矩阵 matrix 如下:

[

[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]

]

给定 target = 5,返回 true。

给定 target = 20,返回 false。

解法

  • 暴力解法:所有循环完一定能找着
  • 使用 map :和暴力循环差不多
  • 二分查找:根据题目的非递减,首先想到的就是二分法
  • Z字形查找,也是利用了非递减。但是时间复杂度是 n+m;二分法是 nlog(m)
public class 二维数组中的查找 {

    public static void main(String[] args) {
        int[][] nums = {{1, 2, 4, 5}, {6, 7, 8, 9}, {10, 11, 12, 13}, {20, 21, 22, 23}};
        int target = 100;
        // 两种形式差不多,都得挨个遍历
        //        baoliDeal(nums, target);
        //        mapDeal(nums, target);

        /**
* 使用二分查找。因为题目给出的就是行列都是非递减。一般这种非递减或者非递增的,应该都要想到二分法
* 时间复杂度 O(nlogm);空间复杂度:O(1)
*/
        //        binarySearch(nums, target);

        //Z字形查找;时间复杂度O(m+n);空间复杂度 O(1)
        ZSearch(nums, target);
    }

    public static void baoliDeal(int[][] nums, int target) {
        boolean is = false;
        for (int i = 0; i < nums.length; i++) {
            for (int j = 0; j < nums[i].length; j++) {
                if (nums[i][j] == target) {
                    is = true;
                    System.out.println(is);
                    break;
                }
            }
            if (is) {
                break;
            }
        }
        if (!is) {
            System.out.println(is);
        }
    }

    public static void mapDeal(int[][] nums, int target) {
        boolean is = false;
        Map map = new HashMap();
        map.put(target, target);
        for (int i = 0; i < nums.length; i++) {
            for (int j = 0; j < nums[i].length; j++) {
                if (map.containsKey(nums[i][j])) {
                    is = true;
                    System.out.println(is);
                    break;
                }
            }
            if (is) {
                break;
            }
        }
        if (!is) {
            System.out.println(is);
        }
    }

    public static void binarySearch(int[][] nums, int target) {
        boolean is = false;
        int x = nums.length;
        int y = nums[x - 1].length;

        if (x == 0 || y == 0) {
            System.out.println("没有匹配的值:" + 00);
        }

        if (target > nums[x - 1][y - 1] || target < nums[0][0]) {
            //直接返回
            System.out.println("没有匹配的值:" + false);
        }
        int l = 0, r = 0, m = 0;
        for (int i = 0; i < x; i++) {
            l = 0;
            r = y - 1;
            while (l <= r) {
                m = (r - l) / 2 + l;
                int tmp = nums[i][m];
                if (tmp == target) {
                    System.out.println(true);
                    is = true;
                    break;
                } else if (tmp > target) {
                    r = m - 1;
                } else if (tmp < target) {
                    l = m + 1;
                }
            }
            if (is) {
                break;
            }
        }

        if (!is) {
            System.out.println(false);
        }
    }

    public static void ZSearch(int[][] nums, int target) {
        int i = nums.length - 1;
        int j = 0;
        boolean is=false;
        while (i > 0 && j < nums[i].length) {
            if(nums[i][j]==target){
                is=true;
                System.out.println("有匹配值");
                break;
            }
            else if(nums[i][j]<target){
            ++j;
        }
            else if(nums[i][j]>target){
            --i;
        }
        }
            if(!is){
            System.out.println("没有匹配的值");
        }
        }

        }