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
.
Example:
grid = [[4,3,2,-1],[3,2,1,-1],[1,1,-1,-2],[-1,-1,-2,-3]]
Output: 8
Example:
grid = [[3,2],[1,0]]
Output: 0
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?
## Naive Solution
The brute force solution is to iterate through each element in the matrix and check if it's negative. If it is, increment a counter. This approach has a time complexity of O(m*n), where m is the number of rows and n is the number of columns.
```python
def count_negatives_brute_force(grid):
count = 0
for row in grid:
for num in row:
if num < 0:
count += 1
return count
Since the grid is sorted in non-increasing order both row-wise and column-wise, we can use binary search to find the index of the first negative number in each row. Once we find this index, we know that all elements to the right of this index are also negative. We can then add the number of negative elements in that row to a running total. This approach has a time complexity of O(m * log(n)). We can also optimize this to O(m+n) time complexity by starting from top right.
def count_negatives_binary_search(grid):
count = 0
for row in grid:
left, right = 0, len(row) - 1
while left <= right:
mid = (left + right) // 2
if row[mid] < 0:
right = mid - 1
else:
left = mid + 1
count += len(row) - left
return count
def count_negatives_optimal(grid):
m, n = len(grid), len(grid[0])
row, col = 0, n - 1
count = 0
while row < m and col >= 0:
if grid[row][col] < 0:
count += m - row
col -= 1
else:
row += 1
return count
left
, right
, and mid
.row
, col
, and count
.len(row) - left == 0
.len(row)
to the count.