面试题4:二维数组中的查找

1.引例(简单形式)

在一个二维数组中,每一行按从左到右递增的顺序排列,下一行的第一个元素大于上一行最后一个元素,找出目标数是否在此二维数组中。

1.1分析

此题输入为二维数组,其实质是一维有序数组的问题,将二维数组的元素索引对应一维数组,进而采用二分搜索方法求解。

 1     public static boolean isArrayItem(int[][] array, int target) {
 2         if (array.length == 0) {return false;}
 3         int len = array.length * array[0].length;
 4         int col = array[0].length;
 5         int lo = 0;
 6         int hi = len - 1;
 7         while (lo <= hi) {
 8             int mid = (lo + hi) / 2;
 9             if (array[mid / col][mid % col] == target) {
10                 return true;
11             } else if (array[mid / col][mid % col] > target) {
12                 hi = mid - 1;
13             } else {
14                 lo = mid + 1;
15             }
16         }
17         return false;
18     }

复杂度分析:时间复杂度O(logn),空间复杂度O(1)。

2.题目描述

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

3.分析边界条件及测试用例

1.输入数组为空,测试用例为{};

2.输入的目标值超出数组的范围之内,测试用例为{{1,2,8,9},{2,4,9,12},{4,7,10,13},{6,8,11,15}} ,target = 16;

3.正常的测试案例,输入数组为{{1,2,8,9},{2,4,9,12},{4,7,10,13},{6,8,11,15}} ,target = 5和target = 7。

4.问题求解

求解思路,对于目标值来说,分析输入数组的规律,可以知道每行的最后一个元素比这一行所有元素都大,比其所在列的所有元素都小,通过比较该元素于目标元素,每比较一次就能排除一行或一列元素,减小了运算代价。

 1     public static boolean isSpecificArrayItem(int[][] array, int target) {
 2         if (array.length == 0) {return false;}
 3         int row = array.length;
 4         int col = array[0].length;
 5         if (target < array[0][0] || target > array[row - 1][col - 1]) {
 6             return false;
 7         }
 8         int rIndex = 0;
 9         int cIndex = col - 1;
10         while(rIndex < row && cIndex >= 0) {
11             if (array[rIndex][cIndex] == target) {
12                 return true;
13             } else if (array[rIndex][cIndex] > target) {
14                 cIndex--;
15             } else {
16                 rIndex++;
17             }
18         }
19         return false;
20     }

复杂度分析:时间复杂度O(m+n)(m,n为二维数组两个维度),空间复杂度O(1)。

 

你可能感兴趣的:(面试题4:二维数组中的查找)