给一个M×N矩阵,找一个目标值target是否存在,输出true/false
假设:矩阵每一行都是递增,每一列都是递增
举例
M=3,N=4
{{1,4,7,11},
{3,6,9,13},
{5,8,12,20}
}
9 返回 true
2 返回 false
方法一
由于矩阵每一行都是递增的,所以再每一行上使用二分查找,总的时间复杂度为O(nlgn)
import java.util.Arrays;
public class test {
public static void main(String[] args) {
int[][] m = {{1,4,7,11},{3,6,9,13},{5,8,12,20}};
for(int i = 0; i < m.length; ++i) {
for(int j = 0; j < m[0].length; ++j) {
int target = m[i][j];
boolean flag = binarySearch(m, target);
System.out.println(m[i][j] + " is " + flag);
}
}
}
public static boolean binarySearch(int[][] m, int target) {
for(int i = 0; i < m.length; ++i) {
int low = 0;
int high = m[0].length;
while (low < high) {
int mid = (low + high) / 2;
if (target < m[i][mid]) {
high = mid;
} else if (target > m[i][mid]) {
low = mid + 1;
} else {
return true;
}
}
}
return false;
}
}
为什么不能对列先二分查找确定列呢?
因为第i行的第一个元素不一定比第i-1行最后一行的数字大,当寻找9时,二分查找会在最后一行查找,结果反而是false。
方法二
从右上角开始向左找,当左边数字比target小时,下移一行,比较当前值,重复向前向后找。时间复杂度为O(m+n)
寻找9:
寻找2:
import java.util.Arrays;
public class test {
public static void main(String[] args) {
int[][] m = {{1,4,7,11},{3,6,9,13},{5,8,12,20}};
for(int i = 0; i < m.length; ++i) {
for(int j = 0; j < m[0].length; ++j) {
int target = m[i][j];
boolean flag = search(m, target);
System.out.println(m[i][j] + " is " + flag);
}
}
boolean flag = search(m, 2);
System.out.println("======================================");
System.out.println(2 + " is " + flag);
}
public static boolean search(int[][] m, int target) {
int i = m[0].length-1;
int j = 0;
while(i >= 0 && j < m.length) {
if(m[j][i] == target){
return true;
}
else if(m[j][i] > target){
--i;
}
else if(m[j][i] < target){
++j;
}
}
return false;
}
}
结果如下: