public class Solution {
    public int[] KWeakestRows(int[][] mat, int k) {
        var pq = new PriorityQueue<int, (int s, int i)>(
            Comparer<(int s, int i)>.Create((a, b) => b.CompareTo(a)));
 
        for (int i = 0; i < mat.Length; i++) {
            int count = 0;
            while (count < mat[i].Length && mat[i][count] == 1) count++;
 
            pq.Enqueue(i, (count, i));
            if (pq.Count > k) pq.Dequeue();
        }
 
        var result = new int[k];
        for (int z = k - 1; z >= 0; z--)
            result[z] = pq.Dequeue();
 
        return result;
    }
}

We create a pq where the priority is in the form of a tuple. The comparer is for max heap, and see that the comparer has to be the same type as of the priority tuple.

Now, iterating through the matrix, we fill the pq, such that values are row indices, and priority is tie breaking tuple, of strength then index. Max heap will dequeue largest strengths and largest indices (if tie break), and that is what we want. We want to keep lowest strengths and lowest index if ties.

Then, we iterate the result array backwards, and fill in the values from pq, which gives strongest to weakest backwards in the array.


Actually, a simpler version works. No need to keep k smallest. Just fill in the min heap, and then fill the result from heap by dequeueing till the k length.

var pq = new PriorityQueue<int, (int s, int i)>();
for (int i = 0; i < mat.Length; i++) {
    int count = 0;
    while (count < mat[i].Length && mat[i][count] == 1) count++;
    pq.Enqueue(i, (count, i));
}
 
var result = new int[k];
for (int z = 0; z < k; z++)
    result[z] = pq.Dequeue();
return result;