You are given a binary matrix binaryMatrix with n rows and m columns. Each value in the matrix is either 0 or 1. Each row in the matrix is sorted in non-decreasing order (all the 0s come before 1s in every row).
Your task is to find the index (0-based) of the leftmost column that contains at least a single 1. If no such column exists (i.e., the matrix consists of all 0s), return -1.
0s first, then 1s.get(row, col) to retrieve the value at a specific cell, and dimensions() to get the matrix size.get should be minimized.
At first glance, you might consider checking every cell in the matrix for a 1 and keeping track of the leftmost column index. However, since each row is sorted, we can do better than brute-force.
The key insight is that, because of the row-wise sorting, once you find a 1 in a row, all cells to the right will also be 1s. This means we can skip unnecessary checks and use a more efficient search strategy.
Instead of searching every cell, we can start from the top-right corner and systematically move left or down based on the value we find, which helps us quickly zero in on the leftmost column containing a 1.
We use a stepwise linear search, starting from the top-right corner of the matrix:
n (rows) and m (columns). Start at the top-right cell: row = 0, col = m - 1.
row < n and col >= 0:
binaryMatrix.get(row, col) == 1, move left (decrement col by 1) because there might be a 1 further left.binaryMatrix.get(row, col) == 0, move down (increment row by 1) because this row doesn't have a 1 in this column or any to the left.1s, return the leftmost column index; otherwise, return -1.
This approach ensures we never visit the same cell twice and minimizes the number of API calls.
Suppose binaryMatrix is:
0 0 0 1
0 0 1 1
0 1 1 1
1 → move left to col=2.0 → move down to row=1.1 → move left to col=1.0 → move down to row=2.1 → move left to col=0.0 → move down to row=3 (out of bounds).
The leftmost column index where we found a 1 was at col=1. So, the answer is 1.
O(n * m) time, O(1) space (since we only track the minimum column index).
n + m steps (each step moves either left or down). So time complexity is O(n + m), space is still O(1).
By leveraging the sorted property of each row, we avoid unnecessary checks and minimize API calls. The stepwise linear search from the top-right corner efficiently narrows down the leftmost column containing a 1, resulting in an elegant and optimal solution.
# This assumes you are given a BinaryMatrix API with get and dimensions methods.
class Solution:
def leftMostColumnWithOne(self, binaryMatrix):
n, m = binaryMatrix.dimensions()
row, col = 0, m - 1
answer = -1
while row < n and col >= 0:
if binaryMatrix.get(row, col) == 1:
answer = col
col -= 1
else:
row += 1
return answer
// Assume BinaryMatrix is an interface with get() and dimensions() methods
class Solution {
public:
int leftMostColumnWithOne(BinaryMatrix &binaryMatrix) {
vector<int> dims = binaryMatrix.dimensions();
int n = dims[0], m = dims[1];
int row = 0, col = m - 1;
int answer = -1;
while (row < n && col >= 0) {
if (binaryMatrix.get(row, col) == 1) {
answer = col;
col--;
} else {
row++;
}
}
return answer;
}
};
// Assume BinaryMatrix is an interface with get() and dimensions() methods
class Solution {
public int leftMostColumnWithOne(BinaryMatrix binaryMatrix) {
List<Integer> dims = binaryMatrix.dimensions();
int n = dims.get(0), m = dims.get(1);
int row = 0, col = m - 1;
int answer = -1;
while (row < n && col >= 0) {
if (binaryMatrix.get(row, col) == 1) {
answer = col;
col--;
} else {
row++;
}
}
return answer;
}
}
/**
* @param {BinaryMatrix} binaryMatrix
* @return {number}
*/
var leftMostColumnWithOne = function(binaryMatrix) {
const [n, m] = binaryMatrix.dimensions();
let row = 0, col = m - 1;
let answer = -1;
while (row < n && col >= 0) {
if (binaryMatrix.get(row, col) === 1) {
answer = col;
col--;
} else {
row++;
}
}
return answer;
};