
Problem Statement
The task is to develop a function that can navigate through an m x n
matrix of integers. This matrix is organized in such a way that both rows and columns are sorted in a non-increasing order. The primary goal of the function is to count and return the total number of negative numbers contained within the matrix. This has direct real-world applications where matrices are used to represent various types of data that can possess dual sorting, and a specific count of certain value types (negative numbers in this case) is required for further processing or decision-making.
Examples
Example 1
Input:
grid = [[4,3,2,-1],[3,2,1,-1],[1,1,-1,-2],[-1,-1,-2,-3]]
Output:
8
Explanation:
There are 8 negatives number in the matrix.
Example 2
Input:
grid = [[3,2],[1,0]]
Output:
0
Constraints
m == grid.length
n == grid[i].length
1 <= m, n <= 100
-100 <= grid[i][j] <= 100
Approach and Intuition
Given that the matrix is sorted in non-increasing order both row-wise and column-wise, we can leverage this property to optimize the counting of negative numbers. Here's a logical approach to tackle this:
Understand Matrix Properties: Recognize that the top-right or bottom-left corner of the matrix can serve as a starting point for checking negative numbers efficiently. If you start from the top-right corner, the movement strategy can be outlined as follows: if a negative number is found, every element below in the same column is also negative (due to the column-wise sorting).
Efficiently Navigate through the Matrix:
- Start from the top-right corner of the matrix.
- If the number is negative, all the numbers below in that column are also negative (because the matrix is sorted in non-increasing order column-wise). Add all these numbers to the negative count and move left to check the next column.
- If the number is non-negative, move downward to the next row while staying in the same column as the numbers to the left might still be negative.
Iterative Counting:
- Initialize a counter for negative numbers.
- Use two pointers or indices (one for rows and another for columns) to navigate through the matrix based on the conditions mentioned above.
- Increment the counter appropriately as each negative number is identified.
End Condition:
- The process can terminate early if the leftmost column or the bottommost row is reached without finding further negative numbers.
Edge cases:
- Consider edge cases where the smallest matrix dimension is 1 (either 1 row or 1 column), or where there are no negative numbers at all.
By implementing the above method, the function can minimize the number of elements it needs to examine, thus enhancing efficiency particularly in larger matrices, making use of the sorted property to skip entire sections of the matrix that do not require examination.
Solutions
- C++
- Java
- JavaScript
- Python
class Solution {
public:
int countNegatives(vector<vector<int>>& matrix) {
int negativeCount = 0;
int columnCount = matrix[0].size();
int negativeStartIndex = columnCount - 1;
for (auto& eachRow : matrix) {
while (negativeStartIndex >= 0 && eachRow[negativeStartIndex] < 0) {
negativeStartIndex--;
}
negativeCount += (columnCount - (negativeStartIndex + 1));
}
return negativeCount;
}
};
The provided C++ solution efficiently counts the number of negative numbers in a sorted matrix, where each row is sorted in non-increasing order. Upon examining the code, one recognizes a strategy that combines a linear traversal of the matrix rows with a linear scan from the end of each row. This is aimed at quickly locating the transition point between non-negative and negative numbers.
Here's the solution breakdown:
- Initialize
negativeCount
to accumulate the number of negative numbers across all the rows. - Utilize
columnCount
to hold the total number of elements in a row for easy indexing. - Start
negativeStartIndex
from the last element of the row, aiming to find the first negative number in reverse order. - Iterate through each row in the matrix with a for-loop.
- Inside the loop, use while-loop to decrement
negativeStartIndex
as long as the elements are negative, stopping when a non-negative value is encountered or when it exceeds the row boundaries. - Update
negativeCount
after each row iteration, adding up the number of negative elements from the current row based on the final position ofnegativeStartIndex
. - The function finally returns
negativeCount
, representing the total count of negative numbers in the matrix.
The algorithm leverages the sorted nature of the matrix to effectively reduce the number of required comparisons, offering a more direct path to counting negatives without checking each element individually. This approach is more efficient than a brute-force method, especially for larger matrices or matrices with many negative numbers skewed towards the end of each row.
int totalNegatives = 0;
int columns = grid[0].length;
int lastPositiveIndex = columns - 1;
for (int[] eachRow : grid) {
while (lastPositiveIndex >= 0 && eachRow[lastPositiveIndex] < 0) {
lastPositiveIndex--;
}
totalNegatives += (columns - (lastPositiveIndex + 1));
}
return totalNegatives;
The provided Java code efficiently counts the number of negative numbers in a sorted matrix where each row is sorted in non-decreasing order. Here's a breakdown of how the code accomplishes this:
- Initialize
totalNegatives
to keep track of the number of negative elements throughout the matrix. - Determine the number of columns in the matrix with
columns = grid[0].length;
. - Use
lastPositiveIndex
to find the transition point between positive and negative numbers in each row. It starts at the last index of each row. - Iterate over each row of the matrix. For each row:
- Utilize a while loop to decrement
lastPositiveIndex
as long as the current element at this index is negative. This helps in finding the first negative element of the row. - Add the count of negative numbers in the current row to
totalNegatives
by subtracting the position of the first non-negative number from the total number of columns.
- Utilize a while loop to decrement
- Finally, return
totalNegatives
, which now contains the count of all negative numbers in the matrix.
This approach leverages the sorted nature of the matrix efficiently by minimizing the number of elements checked in each row once the first negative element is found.
var countNegativeNumbers = function(matrix) {
let totalNegatives = 0;
let columns = matrix[0].length;
let lastPositiveIndex = columns - 1;
for (let currentRow of matrix) {
while (lastPositiveIndex >= 0 && currentRow[lastPositiveIndex] < 0) {
lastPositiveIndex--;
}
totalNegatives += (columns - (lastPositiveIndex + 1));
}
return totalNegatives;
};
The provided solution counts the number of negative numbers in a matrix that is sorted in non-increasing order both row-wise and column-wise. The JavaScript function countNegativeNumbers
uses an efficient approach leveraging the matrix's sorted property.
- Start by initializing
totalNegatives
to zero to keep track of the negative numbers. - Determine the number of columns in the matrix with
columns = matrix[0].length
. - Initialize
lastPositiveIndex
to the last index of a row since the matrix is sorted in a non-increasing order. - Use a
for
loop to iterate through each row of the matrix usingcurrentRow
. - Within the loop, use a
while
loop to update thelastPositiveIndex
. This loop decrementslastPositiveIndex
until a non-negative number is found or it reaches the beginning of the row. - Calculate the number of negative numbers in the current row by subtracting
(lastPositiveIndex + 1)
fromcolumns
and add it tototalNegatives
. - Finally, return the
totalNegatives
.
This method significantly reduces the search space by not re-evaluating the positions in each row starting from the end every time, as the sorted nature means once a negative number is found, all subsequent numbers to the left are also negative. This makes the function run efficiently even for larger matrices.
class Solution:
def negativeCount(self, matrix: List[List[int]]) -> int:
total_negatives = 0
columns = len(matrix[0])
last_positive_index = columns - 1
# Process each row in the matrix to count negatives
for row in matrix:
# Adjust 'last_positive_index' to always point to last non-negative element in the row
while last_positive_index >= 0 and row[last_positive_index] < 0:
last_positive_index -= 1
# Using 'last_positive_index', count the negatives in current row
total_negatives += (columns - (last_positive_index + 1))
return total_negatives
The provided Python solution efficiently counts all negative numbers in a matrix that is sorted in non-descending order by row and column. The matrix is represented as a list of lists, where each inner list is a row of the matrix.
Here's a brief rundown of the implemented logic:
- Initialize a counter
total_negatives
to track the total count of negative numbers across all rows. - Determine the number of columns in the matrix by getting the length of the first row.
last_positive_index
is initialized to the last index of each row; it indicates the boundary index beyond which elements become negative.
For each row in the matrix:
- Adjust
last_positive_index
to always point to the last non-negative element in the current row. This is performed by checking elements from the currentlast_positive_index
backwards until a negative number is encountered. - Calculate the number of negative numbers in the current row by subtracting
last_positive_index + 1
(the index of the first negative element) from the total number of columns. - Accumulate the count of negatives for each row into
total_negatives
.
Finally, the function returns the total count of negative numbers in the matrix. This approach ensures that the function only scans back from the last positive index identified in the previous row, leveraging the sorted order of the rows to reduce the number of comparisons and thus improve efficiency.
No comments yet.