给你一个满足下述两条属性的 m x n
整数矩阵:
- 每行中的整数从左到右按非严格递增顺序排列。
- 每行的第一个整数大于前一行的最后一个整数。
给你一个整数 target
,如果 target
在矩阵中,返回 true
;否则,返回 false
。
示例 1:
输入:matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 3 输出:true
示例 2:
输入:matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 13 输出:false
提示:
m == matrix.length
n == matrix[i].length
1 <= m, n <= 100
-104 <= matrix[i][j], target <= 104
代码:
/*将矩阵看成一个有序的一维数组使用二分法,例如示例一可以看成[1,3,5,7,10,11,16,20,23,30,36,40] 二分法是向下取整 */
bool searchMatrix(int** matrix, int matrixSize, int* matrixColSize, int target) {
int m = matrixSize,n = matrixColSize[0];
if(m==0 || n==0){
return false; //行或者列为0则是空矩阵,返回false
}
int l = 0,r = m*n-1;
while(l<=r){
int mid = l + (r-l)/2;
int hang = mid/n; //除法得到行
int lie = mid%n; //取余得到列
if(matrix[hang][lie]==target){
return true;
}else if(matrix[hang][lie]>target){ //二分法
r = mid-1;
}else{
l = mid+1;
}
}
return false;
}
补充:
数学推导:如何从一维索引反推二维坐标?
以示例一来计算
[1,3,5,7,10,11,16,20,23,30,36,40]
对于任意一维索引 mid
(范围 0
到 行×列-1
),我们要找到对应的二维坐标 (hang, lie)
:
行号 的计算:
- 每一行有
n
个元素,因此mid
所在的行号等于mid
除以 lie 的整数部分。 - 例如:
mid = 1
时,1÷ 4 = 0
余1
,说明mid
在第 0 行(从 0 开始计数)。mid = 8
时,8 ÷ 4 = 2
余0
,说明mid
在第2
行。
- 每一行有
列号
col
的计算:mid
除以n
的余数即为列号。- 例如:
mid = 1
时,余数为1
,说明mid
在第1
行的第1
列(对应二维矩阵中的元素 3)。mid = 8
时,余数为0
,说明mid
在第2
行的第0
列(对应元素23
)。