描述
在一个二维数组array中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
[
[1,2,8,9],
[2,4,9,12],
[4,7,10,13],
[6,8,11,15]
]
给定 target = 7,返回 true。
给定 target = 3,返回 false。
数据范围:矩阵的长宽满足 0 \le n,m \le 5000≤n,m≤500 , 矩阵中的值满足 0 \le val \le 10^90≤val≤109
进阶:空间复杂度 O(1)O(1) ,时间复杂度 O(n+m)O(n+m)
示例1
输入:
7,[[1,2,8,9],[2,4,9,12],[4,7,10,13],[6,8,11,15]]
返回值:
true
说明:
存在7,返回true
示例2
输入:
1,[[2]]
返回值:
false
示例3
输入:
3,[[1,2,8,9],[2,4,9,12],[4,7,10,13],[6,8,11,15]]
返回值:
false
说明:
不存在3,返回false
解题思路:
在m*n的数组arr中(杨氏矩阵),第m行的第1列数字和第n列的第1行数字是比较又特点的,arr[m-1][0]>arr[m-2][0](他的上一行的同一列的数小于它,即纵向递增),arr[m-1][0]M<arr[m-1][1](他的同一行的下一个数大于它,即横向递增)
我们可以以这样一个性质去设计解题思路。
从第m行的第1列开始。
1.只要target(目标值)>arr[i][col],那么就执行操作col++(arr需要增加);
2.如果target(目标值)<arr[i][col],那么就执行操作i--(因为此矩阵从上到下增加,所以i--是从下到上减少,arr的值需要减小);
3.如果target(目标值)=arr[i][col],直接返回true。
要执行上述三个选择结构就需要用到循环结构,不难想到循环结构的终止条件如下:
①i>=0,即当执行到第1行第1列的时候(因为第1行的下标等于0,所以包含i=0),当执行到arr[0][0]的时候终止(到本二维数组中最小的数的时候),也就意味着目标值比本二维数组最小值还要小;
②col<arr的列数,当执行到arr[m-1][n-1]斜对角的时候终止(到本二维数组中最大的数的时候),也就意味着目标值比本二维数组最大值还要大。
执行步骤图如下:
当前值(stpe1) | ||||
i=3 | col=0 | arr=6 | 执行操作 | col++ |
正在比较 | 已经比较 | 即将比较 | 未比较 | 目标>arr |
数组下标 | col=0 | col=1 | col=3 | col=4 |
i=0 | 1 | 2 | 8 | 9 |
i=1 | 2 | 4 | 9 | 12 |
i=2 | 4 | 7 | 10 | 13 |
i=3 | 6 | 8 | 11 | 15 |
当前值(stpe2) | ||||
i=3 | col=1 | arr=6 | 执行操作 | i-- |
正在比较 | 已经比较 | 即将比较 | 未比较 | 目标<arr |
数组下标 | col=0 | col=1 | col=3 | col=4 |
i=0 | 1 | 2 | 8 | 9 |
i=1 | 2 | 4 | 9 | 12 |
i=2 | 4 | 7 | 10 | 13 |
i=3 | 6 | 8 | 11 | 15 |
当前值(stpe3) | ||||
i=2 | col=1 | arr=6 | 执行操作 | 返回True |
正在比较 | 已经比较 | 即将比较 | 未比较 | 目标=arr |
数组下标 | col=0 | col=1 | col=3 | col=4 |
i=0 | 1 | 2 | 8 | 9 |
i=1 | 2 | 4 | 9 | 12 |
i=2 | 4 | 7 | 10 | 13 |
i=3 | 6 | 8 | 11 | 15 |
代码如下:
bool Find(int target, int** array, int arrayRowLen, int* arrayColLen ) {
int i=arrayRowLen-1,col=0;
while(i>=0&&col<*arrayColLen){
if(array[i][col]>target){
i--;
}else if(array[i][col]<target){
col++;
}else{
return true;
}
}
return false;
}