本题有三种做法,从最开始我想到的就是相对最简单的分治法。
从右下角开始向左上角移动,当该处数值小于target时,递归调用查找左下和右上两个子问题。在原理正确的情况下如果超时,一定要删除其中的打印啊!!!System.out占用非常多的时间,坑爹。
时间复杂度的计算为T(n)=2*T(n/2)+c,算去吧。
代码如下:
public class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
if(matrix==null)return false;
int row = matrix.length;
int col = matrix[0].length;
return partSearch(matrix, 0, 0, row-1, col-1, target);
}
private static boolean partSearch(int[][] matrix,int a,int b,int c,int d,int target){
boolean result = false;
int i=c,j=d;
int temp = matrix[i][j];
if(target>temp)return false;
while(i>=a&&j>=b&&temp>target){
i--;
j--;
if(i<a||j<b)break;
else temp = matrix[i][j];
}
if(temp==target)result = true;
else if(i<a&&j<b)result = false;
else if(i<a&&j>=b)result=partSearch(matrix,a,b,c,j,target);
else if(i>=a&&j<b)result=partSearch(matrix, a, b, i, d, target);
else result=partSearch(matrix, a, j+1, i, d, target)||partSearch(matrix, i+1, b, c, j, target);
return result;
}
}
第二种做法依然从已排序这个角度切入,从右上角出发,若比target小则删除一行,若比target大则删除一列。
代码如下:
public static boolean searchMatrix(int[][] matrix, int target) {
if(matrix==null)return false;
int row = matrix.length;
int col = matrix[0].length;
int i=0,j=col-1;
boolean result = false;
while(i<=row-1&&j>=0){
if(matrix[i][j]==target){
System.out.println(matrix[i][j]);
result = true;
break;
}else if(matrix[i][j]<target)i++;
else if(matrix[i][j]>target)j--;
}
return result;
}
第三种做法也就是最笨的做法,用二分查找遍历n次。
代码如下:
public class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
boolean result = false;
for(int i=0;i<matrix.length&&!result;i++){
result = binarySearch(matrix[i], 0, matrix[0].length-1, target);
}
return result;
}
private boolean binarySearch(int[] nums,int i,int j,int target){
while(i<=j){
int mid = (i+j)/2;
if(nums[mid]<target)return binarySearch(nums, mid+1, j,target);
else if(nums[mid]>target)return binarySearch(nums, i, mid-1, target);
else return true;
}
return false;
}
}