Search 2D Matrix
You are given an m x n 2-D integer array matrix and an integer target.
Each row in matrix is sorted in non-decreasing order.
The first integer of every row is greater than the last integer of the previous row.
Return true if target exists within matrix or false otherwise.
Can you write a solution that runs in O(log(m * n)) time?
Example 1:
Input: matrix = [[1,2,4,8],[10,11,12,13],[14,20,30,40]], target = 10
Output: true
Example 2:
Input: matrix = [[1,2,4,8],[10,11,12,13],[14,20,30,40]], target = 15
Output: false
Constraints:
m == matrix.length
n == matrix[i].length
1 <= m, n <= 100
-10000 <= matrix[i][j], target <= 10000
Solution
This is a 2D binary search, all we need to do is modifying the middle position of 1D binary search. The time complexity is O(log(n×m))=O(logn+logm)O(\log(n\times m))=O(\log n+\log m)O(log(n×m))=O(logn+logm).
It is also plausible to apply 1D binary search twice. In the first time we try to find the row and in the second time we try to find the column. The time complexity is also O(logn+logm)O(\log n+ \log m)O(logn+logm)
Code
Because the problem requires us to find an exact number, so it is better to use binary search in a closed interval.
class Solution:
def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
n = len(matrix)
m = len(matrix[0])
le = 0
ri = n*m-1
mid = 0
while le <= ri:
mid = (le+ri)//2
x = mid//m
y = mid%m
if matrix[x][y] == target:
break
if matrix[x][y] < target:
le = mid+1
else:
ri = mid-1
x = mid//m
y = mid%m
return matrix[x][y] == target
Open interval version:
class Solution:
def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
n = len(matrix)
m = len(matrix[0])
le = 0
ri = n*m
while le < ri:
mid = (le+ri)//2
x = mid//m
y = mid%m
print(mid, x, y)
if matrix[x][y] < target:
le = mid+1
else:
ri = mid
if le >= n*m:
return False
x = le//m
y = le%m
return matrix[x][y] == target