Off-by-one on range boundaries
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Build confidence with an intuition-first walkthrough focused on array fundamentals.
You are given an m x n binary matrix mat of 1's (representing soldiers) and 0's (representing civilians). The soldiers are positioned in front of the civilians. That is, all the 1's will appear to the left of all the 0's in each row.
A row i is weaker than a row j if one of the following is true:
i is less than the number of soldiers in row j.i < j.Return the indices of the k weakest rows in the matrix ordered from weakest to strongest.
Example 1:
Input: mat = [[1,1,0,0,0], [1,1,1,1,0], [1,0,0,0,0], [1,1,0,0,0], [1,1,1,1,1]], k = 3 Output: [2,0,3] Explanation: The number of soldiers in each row is: - Row 0: 2 - Row 1: 4 - Row 2: 1 - Row 3: 2 - Row 4: 5 The rows ordered from weakest to strongest are [2,0,3,1,4].
Example 2:
Input: mat = [[1,0,0,0], [1,1,1,1], [1,0,0,0], [1,0,0,0]], k = 2 Output: [0,2] Explanation: The number of soldiers in each row is: - Row 0: 1 - Row 1: 4 - Row 2: 1 - Row 3: 1 The rows ordered from weakest to strongest are [0,2,3,1].
Constraints:
m == mat.lengthn == mat[i].length2 <= n, m <= 1001 <= k <= mmatrix[i][j] is either 0 or 1.Problem summary: You are given an m x n binary matrix mat of 1's (representing soldiers) and 0's (representing civilians). The soldiers are positioned in front of the civilians. That is, all the 1's will appear to the left of all the 0's in each row. A row i is weaker than a row j if one of the following is true: The number of soldiers in row i is less than the number of soldiers in row j. Both rows have the same number of soldiers and i < j. Return the indices of the k weakest rows in the matrix ordered from weakest to strongest.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Array · Binary Search
[[1,1,0,0,0],[1,1,1,1,0],[1,0,0,0,0],[1,1,0,0,0],[1,1,1,1,1]] 3
[[1,0,0,0],[1,1,1,1],[1,0,0,0],[1,0,0,0]] 2
Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #1337: The K Weakest Rows in a Matrix
class Solution {
public int[] kWeakestRows(int[][] mat, int k) {
int m = mat.length, n = mat[0].length;
int[] res = new int[m];
List<Integer> idx = new ArrayList<>();
for (int i = 0; i < m; ++i) {
idx.add(i);
int[] row = mat[i];
int left = 0, right = n;
while (left < right) {
int mid = (left + right) >> 1;
if (row[mid] == 0) {
right = mid;
} else {
left = mid + 1;
}
}
res[i] = left;
}
idx.sort(Comparator.comparingInt(a -> res[a]));
int[] ans = new int[k];
for (int i = 0; i < k; ++i) {
ans[i] = idx.get(i);
}
return ans;
}
}
// Accepted solution for LeetCode #1337: The K Weakest Rows in a Matrix
func kWeakestRows(mat [][]int, k int) []int {
m, n := len(mat), len(mat[0])
res := make([]int, m)
var idx []int
for i, row := range mat {
idx = append(idx, i)
left, right := 0, n
for left < right {
mid := (left + right) >> 1
if row[mid] == 0 {
right = mid
} else {
left = mid + 1
}
}
res[i] = left
}
sort.Slice(idx, func(i, j int) bool {
return res[idx[i]] < res[idx[j]] || (res[idx[i]] == res[idx[j]] && idx[i] < idx[j])
})
return idx[:k]
}
# Accepted solution for LeetCode #1337: The K Weakest Rows in a Matrix
class Solution:
def kWeakestRows(self, mat: List[List[int]], k: int) -> List[int]:
m, n = len(mat), len(mat[0])
ans = [n - bisect_right(row[::-1], 0) for row in mat]
idx = list(range(m))
idx.sort(key=lambda i: ans[i])
return idx[:k]
// Accepted solution for LeetCode #1337: The K Weakest Rows in a Matrix
struct Solution;
use std::collections::BinaryHeap;
type Pair = (i32, usize);
impl Solution {
fn k_weakest_rows(mat: Vec<Vec<i32>>, k: i32) -> Vec<i32> {
let mut pq: BinaryHeap<Pair> = BinaryHeap::new();
let n = mat.len();
for i in 0..n {
let sum = mat[i].iter().sum::<i32>();
let pair = (sum, i);
pq.push(pair);
if pq.len() > k as usize {
pq.pop();
}
}
let mut res: Vec<i32> = vec![];
while !pq.is_empty() {
let biggest = pq.pop().unwrap();
res.push(biggest.1 as i32);
}
res.reverse();
res
}
}
#[test]
fn test() {
let mat: Vec<Vec<i32>> = [
[1, 1, 0, 0, 0],
[1, 1, 1, 1, 0],
[1, 0, 0, 0, 0],
[1, 1, 0, 0, 0],
[1, 1, 1, 1, 1],
]
.iter()
.map(|v| v.to_vec())
.collect();
let k = 3;
let res = vec![2, 0, 3];
assert_eq!(Solution::k_weakest_rows(mat, k), res);
}
// Accepted solution for LeetCode #1337: The K Weakest Rows in a Matrix
function kWeakestRows(mat: number[][], k: number): number[] {
let n = mat.length;
let sumMap = mat.map((d, i) => [d.reduce((a, c) => a + c, 0), i]);
let ans = [];
// 冒泡排序
for (let i = 0; i < k; i++) {
for (let j = i; j < n; j++) {
if (
sumMap[j][0] < sumMap[i][0] ||
(sumMap[j][0] == sumMap[i][0] && sumMap[i][1] > sumMap[j][1])
) {
[sumMap[i], sumMap[j]] = [sumMap[j], sumMap[i]];
}
}
ans.push(sumMap[i][1]);
}
return ans;
}
Use this to step through a reusable interview workflow for this problem.
Check every element from left to right until we find the target or exhaust the array. Each comparison is O(1), and we may visit all n elements, giving O(n). No extra space needed.
Each comparison eliminates half the remaining search space. After k comparisons, the space is n/2ᵏ. We stop when the space is 1, so k = log₂ n. No extra memory needed — just two pointers (lo, hi).
Review these before coding to avoid predictable interview regressions.
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Wrong move: Setting `lo = mid` or `hi = mid` can stall and create an infinite loop.
Usually fails on: Two-element ranges never converge.
Fix: Use `lo = mid + 1` or `hi = mid - 1` where appropriate.