题目:
Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties:
- Integers in each row are sorted in ascending from left to right.
- Integers in each column are sorted in ascending from top to bottom.
For example,
Consider the following matrix:
[ [1, 4, 7, 11, 15], [2, 5, 8, 12, 19], [3, 6, 9, 16, 22], [10, 13, 14, 17, 24], [18, 21, 23, 26, 30] ]
Given target = 5
, return true
.
Given target = 20
, return false
.
链接:https://leetcode.com/problems/search-a-2d-matrix-ii/#/description
4/27/2017
53%, 15ms
从右上和左下两个方向进行,缩小范围到left/right重合或者交叉,或者top/bottom重合交叉。
注意第25-27行没有的话对结果也没有影响,但是缺少的话最后一个else其实是包含了很多非法情况的。
1 public class Solution { 2 public boolean searchMatrix(int[][] matrix, int target) { 3 if (matrix == null || matrix.length == 0 || matrix[0].length == 0) { 4 return false; 5 } 6 7 int right = matrix[0].length - 1, left = 0, top = 0, bottom = matrix.length - 1; 8 while (left < right && top < bottom) { 9 if (matrix[top][right] < target) { 10 top++; 11 } else if (matrix[top][right] > target) { 12 right--; 13 } else { 14 return true; 15 } 16 if (matrix[bottom][left] < target) { 17 left++; 18 } else if (matrix[bottom][left] > target) { 19 bottom--; 20 } else { 21 return true; 22 } 23 } 24 25 if (right < left || bottom < top) { 26 return false; 27 } 28 if (right == left) { 29 while (top + 1 < bottom) { 30 int mid = top + (bottom - top) / 2; 31 if (matrix[mid][right] == target) { 32 return true; 33 } else if (matrix[mid][right] > target) { 34 bottom = mid; 35 } else { 36 top = mid; 37 } 38 } 39 if (matrix[top][right] == target || matrix[bottom][right] == target) { 40 return true; 41 } else { 42 return false; 43 } 44 } else { 45 while (left + 1 < right) { 46 int mid = left + (right - left) / 2; 47 if (matrix[top][mid] == target) { 48 return true; 49 } else if (matrix[top][mid] > target) { 50 right = mid; 51 } else { 52 left = mid; 53 } 54 } 55 if (matrix[top][right] == target || matrix[top][left] == target) { 56 return true; 57 } else { 58 return false; 59 } 60 } 61 } 62 }
别人的算法:
只需要从右上开始,比target大就是right--,比target小就top++,直到找到target或者超出边界
https://discuss.leetcode.com/topic/20064/my-concise-o-m-n-java-solution
1 public class Solution { 2 public boolean searchMatrix(int[][] matrix, int target) { 3 if(matrix == null || matrix.length < 1 || matrix[0].length <1) { 4 return false; 5 } 6 int col = matrix[0].length-1; 7 int row = 0; 8 while(col >= 0 && row <= matrix.length-1) { 9 if(target == matrix[row][col]) { 10 return true; 11 } else if(target < matrix[row][col]) { 12 col--; 13 } else if(target > matrix[row][col]) { 14 row++; 15 } 16 } 17 return false; 18 } 19 }
很有意思的divide-conquer方法,虽然效率并不高。时间复杂度并不是评论中所说的那么少。
https://discuss.leetcode.com/topic/33240/java-an-easy-to-understand-divide-and-conquer-method
下面是关于这个解法的时间复杂度的讨论,可以看看最后2个链接
https://discuss.leetcode.com/topic/33240/java-an-easy-to-understand-divide-and-conquer-method/15
更多讨论:
https://discuss.leetcode.com/category/301/search-a-2d-matrix-ii