Given a m x n
matrix grid
which is sorted in non-increasing order both row-wise and column-wise, return the number of negative numbers in grid
.
For example, consider this grid:
[
[4, 3, 2, -1],
[3, 2, 1, -1],
[1, 1, -1, -2],
[-1, -1, -2, -3]
]
In this example, the correct output is 8 because there are 8 negative numbers in the matrix.
As another example, consider this grid:
[
[3, 2],
[1, 0]
]
In this example, the correct output is 0 because there are no negative numbers in the matrix.
Constraints:
m == grid.length
n == grid[i].length
1 <= m, n <= 100
-100 <= grid[i][j] <= 100
Could you find an O(n + m)
solution?
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:
The brute force method for this problem involves examining each number in the matrix one by one. The goal is simply to count how many of those numbers are negative. We don't use any of the sorted properties.
Here's how the algorithm would work step-by-step:
def count_negatives_brute_force(matrix):
negative_count = 0
number_of_rows = len(matrix)
number_of_columns = len(matrix[0]) if number_of_rows > 0 else 0
# Iterate through each row of the matrix
for row_index in range(number_of_rows):
# Iterate through each column of the current row
for column_index in range(number_of_columns):
current_number = matrix[row_index][column_index]
# Check if the current number is negative
if current_number < 0:
# Increment the negative count since we found a negative number
negative_count += 1
return negative_count
The straightforward way to count negative numbers is too slow. We can do better by starting in a special corner of the matrix and using the sorted nature of the data to quickly eliminate large portions of the matrix from consideration.
Here's how the algorithm would work step-by-step:
def count_negatives(grid):
number_of_rows = len(grid)
number_of_columns = len(grid[0])
current_row = 0
current_column = number_of_columns - 1
negative_count = 0
while current_row < number_of_rows and current_column >= 0:
# Starting from top-right, check the current element
if grid[current_row][current_column] < 0:
# All elements below are negative
negative_count += number_of_rows - current_row
current_column -= 1
else:
# Move to the next row if the element is non-negative
current_row += 1
return negative_count
Case | How to Handle |
---|---|
Null or empty grid | Return 0, as there are no numbers to count in an empty grid. |
Grid with zero rows or zero columns | Return 0, as an effectively empty grid contains no negative numbers. |
Grid with a single row containing only positive numbers | Return 0, as no negative numbers are present to count. |
Grid with a single row containing only negative numbers | Return the number of columns, as all numbers are negative. |
Grid with all elements as zero | Return 0, as zero is not a negative number. |
Grid with all elements as the smallest possible integer | Return rows * cols, as all elements will be negative. |
Grid with dimensions close to integer limits (large row/col count) | Ensure the counting algorithm doesn't cause integer overflow, particularly if multiplying row/col counts. |
Grid with a mix of very large positive numbers and very small negative numbers | Standard comparison operators should handle both extremes correctly without special handling. |