题目链接:https://leetcode.com/problems/search-a-2d-matrix/description/
题目大意:一个矩阵,从左到右有序排列(未给升序或降序),从上到下,从小到大排列。给出一个target值,在这个矩阵中找找是否有该值,如果有返回true,否则返回false。
解法一:将target与每层的最后一个数值进行比较,找到该target所在的行,然后再在当前行进行二分查找。注意开始要排除矩阵为[],[[]]的特殊情况,否则会导致数组越界。代码如下(耗时12ms):
1 public boolean searchMatrix(int[][] matrix, int target) { 2 //处理特殊情况 3 if(matrix == null || matrix.length == 0 || matrix[0].length == 0) { 4 return false; 5 } 6 int pos = 0; 7 int length = matrix[0].length; 8 //找到所在行 9 for(int i = 0; i < matrix.length; i++) { 10 if(target <= matrix[i][length - 1]) { 11 pos = i; 12 break; 13 } 14 } 15 //在当前行中进行二分查找 16 int low = 0, high = length - 1; 17 while(low <= high) { 18 int mid = (low + high) / 2; 19 if(matrix[pos][mid] < target) { 20 low = mid + 1; 21 } 22 else if(matrix[pos][mid] > target) { 23 high = mid - 1; 24 } 25 else { 26 return true; 27 } 28 } 29 return false; 30 }
解法二(借鉴):在讨论区找最优解,发现没有很优的,这里借鉴一个不同的解法吧,没有定位某一行,而是将矩阵当成一个序列直接进行的二分查找,只是在定位中间数的时候还是利用了矩阵二维数组定位的。并没有快多少,但是代码短很多。代码如下(耗时13ms):
1 public boolean searchMatrix(int[][] matrix, int target) { 2 if(matrix == null || matrix.length == 0 || matrix[0].length == 0) { 3 return false; 4 } 5 int cols = matrix[0].length; 6 //high指向的是矩阵的最后一个数值,而不是某一行的最后一个数值 7 int low = 0, high = matrix.length * cols - 1; 8 while(low <= high) { 9 int mid = (low + high) / 2; 10 //对于整个序列的中间下标,找到矩阵中的中间下标的值 11 if(matrix[mid / cols][mid % cols] < target) { 12 low = mid + 1; 13 } 14 else if(matrix[mid / cols][mid % cols] > target) { 15 high = mid - 1; 16 } 17 else { 18 return true; 19 } 20 } 21 return false; 22 }
解法三:做了240题,回头利用240的解法三ac了这题。代码完全相同(耗时11ms)。【这个题略有问题,其实默认条件还是跟240一样的】