You are given an m x n
integer matrix matrix
with the following two properties:
Given an integer target
, return true
if target
is in matrix
or false
otherwise.
You must write a solution in O(log(m * n))
time complexity.
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
Constraints:
m == matrix.length
n == matrix[i].length
1 <= m, n <= 100
-104 <= matrix[i][j], target <= 104
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
Imagine a grid of numbers and you need to find a specific target number. The brute force approach means we will look at every single number in the grid, one by one. We'll keep checking until we either find the target or run out of numbers to check.
Here's how the algorithm would work step-by-step:
def search_matrix_brute_force(matrix, target):
number_of_rows = len(matrix)
number_of_cols = len(matrix[0])
for row_index in range(number_of_rows):
# Iterate through each row.
for col_index in range(number_of_cols):
# Iterate through each column in current row.
if matrix[row_index][col_index] == target:
#If target is found return True
return True
# If target not found in the matrix.
return False
The trick is to treat the 2D matrix like one long, sorted list, even though it's shaped like a rectangle. This lets us use a very efficient search method similar to how you'd find a word in a dictionary.
Here's how the algorithm would work step-by-step:
def search_2d_matrix(matrix, target):
if not matrix or not matrix[0]:
return False
number_of_rows = len(matrix)
number_of_columns = len(matrix[0])
left_pointer = 0
right_pointer = number_of_rows * number_of_columns - 1
while left_pointer <= right_pointer:
middle_element = (left_pointer + right_pointer) // 2
row_index = middle_element // number_of_columns
column_index = middle_element % number_of_columns
middle_value = matrix[row_index][column_index]
# Adjust search space based on middle value
if target == middle_value:
return True
# Narrow search to the left half
elif target < middle_value:
right_pointer = middle_element - 1
# Narrow search to the right half
else:
left_pointer = middle_element + 1
return False
Case | How to Handle |
---|---|
matrix is null or empty | Return false immediately, as there are no elements to search. |
matrix has zero rows or zero columns | Return false immediately, as there are no elements to search. |
matrix contains only one row | Binary search this single row to find the target. |
matrix contains only one column | Binary search the first element of each row to find the target. |
target is smaller than the smallest element in the matrix | Return false since the matrix is sorted in non-decreasing order. |
target is larger than the largest element in the matrix | Return false since the matrix is sorted and cannot contain the target. |
Large matrix dimensions that could lead to integer overflow in calculations of indices | Use long integers or alternative formulas that avoid overflow for index calculations, if necessary. |
target equals to the first element of a row | Algorithm should return true once the first element is the target value |