题目
在一个 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("没有匹配的值");
}
}
}