Search a 2D Matrix medium
Problem Statement
Write an efficient algorithm that searches for a target value in an m x n integer matrix. The matrix has the following properties:
- Integers in each row are sorted from left to right.
- The first integer of each row is greater than the last integer of the previous row.
Example 1
Input: matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 3
Output: true
Example 2
Input: matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 13
Output: false
Steps
The key to efficiently solving this problem is to leverage the sorted nature of the matrix. Instead of treating it as a 2D array, we can treat it as a sorted 1D array. This allows us to use binary search for a significantly faster solution than nested loops.
Here's the step-by-step approach:
-
Flatten the matrix (conceptually): Imagine the matrix as a single sorted array. The first row's elements come first, followed by the second row's elements, and so on.
-
Determine the size of the "flattened" array: The total number of elements is
m * n
, wherem
is the number of rows andn
is the number of columns. -
Apply Binary Search: Use binary search on this conceptually flattened array. The key is to adapt the index calculations to map the binary search's mid-point index back to the row and column indices in the original matrix.
-
Return the result: The binary search will return
True
if the target is found andFalse
otherwise.
Explanation
The binary search algorithm efficiently searches a sorted array. By conceptually flattening the matrix, we maintain the sorted property, allowing us to use binary search. The crucial part is the mapping between the linear index used in the binary search and the row and column indices of the matrix.
The left
and right
pointers in the binary search define the search space within the "flattened" array. The mid
index is calculated as the average of left
and right
. Then, we determine the row
and col
of the element at this mid
index in the original matrix. If the matrix element at matrix[row][col]
equals the target, we've found it! If it's less than the target, we adjust the left
pointer; otherwise, we adjust the right
pointer. This continues until the left
pointer surpasses the right
pointer.
Code
def searchMatrix(matrix, target):
"""
Searches for a target value in a sorted 2D matrix using binary search.
Args:
matrix: A list of lists representing the 2D matrix.
target: The integer value to search for.
Returns:
True if the target is found, False otherwise.
"""
if not matrix or not matrix[0]: # Handle empty matrix case
return False
rows = len(matrix)
cols = len(matrix[0])
left = 0
right = rows * cols - 1
while left <= right:
mid = (left + right) // 2
row = mid // cols
col = mid % cols
if matrix[row][col] == target:
return True
elif matrix[row][col] < target:
left = mid + 1
else:
right = mid - 1
return False
Complexity
-
Time Complexity: O(log(m*n)), where 'm' is the number of rows and 'n' is the number of columns. This is due to the binary search algorithm.
-
Space Complexity: O(1). The algorithm uses a constant amount of extra space. It operates in-place without creating large auxiliary data structures.