搜索二维矩阵II题目的思路探讨与源码
搜索二维矩阵II的题目如下图,该题属于数组和二分查找类型的题目,主要考察对于二维数组和二分法的使用和理解。本文的题目作者想到2种方法,分别是二分法和双指针方法,其中二分法使用java进行编写,而双指针方法使用Python进行编写,当然这可能不是最优的解法,还希望各位大佬给出更快的算法。
本人认为该题目可以使用二分法,首先判断矩阵是否为空或者矩阵长度是否为0,如果是则直接返回False结果,然后把矩阵的长宽进行比较,求长宽的最小值,并记录。然后开始遍历矩阵的对角线,并且从对角线的的行列值开始搜索遍历,并且调用遍历函数。在遍历函数内部的逻辑是,如果传入的值是True则搜索这一列,另初始位置为当前对角线的值,然后搜索的终点是矩阵的长或者宽,那么当初始位置比矩阵的长或者宽要小的时候,开始遍历,取一个坐标的中值,如果坐标中值对应的矩阵元素比目标值要小,则下限值变成中值加1,如果坐标中值对应的矩阵元素比目标值要大,则上限值变成中值减去1,如果相等就返回True,行列的思路大致一样,只需要注意下标即可,如果最终未找到元素则返回False并结束程序。那么按照这个思路我们的Java代码如下:
#喷火龙与水箭龟
class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
if (matrix == null || matrix.length == 0) {
return false;
}
int deg = Math.min(matrix.length, matrix[0].length);
for (int jr=0;jr<deg;jr++){
boolean flagX = searchBinary(matrix,target,jr,true);
boolean flagY = searchBinary(matrix,target,jr,false);
if (flagX || flagY) {
return true;
}
}
return false;
}
private boolean searchBinary(int[][] matrix, int target, int start, boolean flag) {
int a = start;
int b = 0;
if(flag){
b = matrix[0].length-1;
}else{
b = matrix.length-1;
}
while(a<=b) {
int ind = (a+b)/2;
if(flag){
if(matrix[start][ind]<target) {
a = ind+1;
}else if(matrix[start][ind]>target) {
b = ind-1;
}else{
return true;
}
}else{
if(matrix[ind][start]<target) {
a = ind+1;
}else if (matrix[ind][start]>target) {
b = ind-1;
}else {
return true;
}
}
}
return false;
}
}
显然,我们还可以使用双指针的方法进行处理,其本质就是利用了矩阵本身的单调顺序的特性。那么首先我们记录矩阵的长和宽的值,然后我们把初始位置定在左下角,也就是纵坐标是矩阵长度减去1,横坐标是0,然后我们分别同时遍历两个维度的值,纵坐标从下往上遍历,横坐标从左往右遍历,每次遍历的时候都去判断矩阵的当前值是不是和目标值相同,如果是则直接返回True并且结束程序,否则如果矩阵的值比目标值要小,那就把横坐标向右移动一下;如果矩阵的值比目标值要大,那就把纵坐标向上移动一下。如果到遍历结束还没有找到目标元素值,那么就返回False并结束程序。所以根据这个思路就可以写出代码,下面是Python代码部分:
#喷火龙与水箭龟
class Solution:
def searchMatrix(self,matrix: List[List[int]], target: int) -> bool:
x=len(matrix)
y=len(matrix[0])
ir=x-1
jr=0
while(ir>=0 and jr<y):
if(matrix[ir][jr]==target):
return True
elif(matrix[ir][jr]<target):
jr=jr+1
elif(matrix[ir][jr]>target):
ir=ir-1
return False
从结果来说java版本的二分法的速度比较一般,但是python版本的双指针方法的速度还不错,但应该是有更多的方法可以进一步提速的,希望朋友们能够多多指教,非常感谢。