Given a row x col
binary matrix matrix
, where each row is sorted in non-decreasing order, return the median of all elements in the matrix.
Example 1:
Input: matrix = [[1,1,2],[1,2,3],[1,3,3]]
Output: 2
Explanation: There are 3 rows with 3 elements each, so the median is the 5th element. The two 1s, two 2s and one 3 are the first 5 elements, so the median is 2.
Example 2:
Input: matrix = [[1,1,2],[1,2,2],[1,3,3]]
Output: 2
Constraints:
row == matrix.length
col == matrix[i].length
1 <= row, col <= 500
1 <= matrix[i][j] <= 106
matrix
is sorted in non-decreasing order.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:
To find the middle value in a set of sorted rows, the brute force approach treats the whole matrix like one big unsorted list. It simply gathers all the numbers together and then finds the middle one after sorting them.
Here's how the algorithm would work step-by-step:
def find_median_brute_force(matrix):
all_numbers = []
# Gather all numbers from the matrix into a single list
for row in matrix:
for number in row:
all_numbers.append(number)
all_numbers.sort()
matrix_size = len(all_numbers)
# Determine if the matrix has an odd or even number of elements
if matrix_size % 2 != 0:
# Odd number of elements, return the middle element
median_index = matrix_size // 2
return all_numbers[median_index]
else:
# Even number of elements, calculate the average of the two middle elements
middle_index_one = matrix_size // 2 - 1
middle_index_two = matrix_size // 2
# Need to calculate average of two middle numbers
median = (all_numbers[middle_index_one] + all_numbers[middle_index_two]) / 2
return median
The best way to find the middle value in a matrix where each row is already sorted is to use a process of elimination. We repeatedly narrow down the possible range of values until we pinpoint the median. This is much faster than looking at every single number in the matrix.
Here's how the algorithm would work step-by-step:
def find_median_row_wise_sorted_matrix(matrix):
number_of_rows = len(matrix)
number_of_columns = len(matrix[0])
minimum_value = matrix[0][0]
maximum_value = matrix[0][number_of_columns - 1]
for row in range(number_of_rows):
minimum_value = min(minimum_value, matrix[row][0])
maximum_value = max(maximum_value, matrix[row][number_of_columns - 1])
desired_count = (number_of_rows * number_of_columns + 1) // 2
while minimum_value < maximum_value:
middle_value = minimum_value + (maximum_value - minimum_value) // 2
count = 0
# Counting elements <= middle_value for each row
for row in range(number_of_rows):
left_pointer = 0
right_pointer = number_of_columns
while left_pointer < right_pointer:
mid = left_pointer + (right_pointer - left_pointer) // 2
if matrix[row][mid] <= middle_value:
left_pointer = mid + 1
else:
right_pointer = mid
count += left_pointer
# Adjust search space based on the count
if count < desired_count:
# Middle value is too small
minimum_value = middle_value + 1
else:
# Middle value is too large or the median
maximum_value = middle_value
return minimum_value
Case | How to Handle |
---|---|
Null or empty matrix | Return appropriate value based on problem definition (e.g., null, -1, throw exception), after checking if the matrix is null or any of its dimensions are zero. |
Matrix with one element | Return that single element as the median. |
Matrix with a large number of rows and columns causing integer overflow | Use long or appropriate data type to prevent integer overflow when calculating the total number of elements (m * n). |
Matrix with all elements being the same value | The binary search will still converge to the correct (and only) median value. |
Matrix with negative numbers | The algorithm works correctly with negative numbers as it relies on the sorted nature of the rows and binary search. |
Matrix with very large positive or negative numbers approaching integer limits | The algorithm works correctly as long as the comparison operators are well-defined for these large numbers within the language. |
Matrix where the median falls between two numbers (even total elements) - only applicable if the prompt asks for ceiling or floor if non-integer | The problem asks to return the middle element when all elements are sorted, thus we search directly for this middle element by count so this is not a concern. |
Rows with significantly varying lengths (though problem states rows are sorted and asks for median of all, assume complete matrix) | Since the problem definition assumes a complete matrix, this edge case is not applicable but otherwise requires appropriate padding or special handling during count calculation if the assumption were not met. |