Find the row with maximum number of 1's

Problem

Given a boolean 2D array, consisting of only 1's and 0's, where each row is sorted. Find the 0-based index of the first row that has the maximum number of 1's. Return the 0-based index of the first row that has the most number of 1s. If no such row exists, return -1.

Examples :

Input: arr[][] = [[0, 1, 1, 1],[0, 0, 1, 1],[1, 1, 1, 1],[0, 0, 0, 0]]
Output: 2
Explanation: Row 2 contains 4 1's (0-based indexing).

Input: arr[][] = [[0, 0], [1, 1]]
Output: 1
Explanation: Row 1 contains 2 1's (0-based indexing).

Solution

In this process, we iterate through each row and count the number of ones present in it. We keep track of the index of the row that has the maximum number of ones so far.

Since each row is sorted and contains only 0’s and 1’s, we can count the number of 1’s in a row using a binary search approach. If we find the last index of 0 or the first index of 1, we can determine the total number of 0’s present. By subtracting the number of 0’s from the total length of the row, we obtain the number of 1’s.

In the binary search, we set ‘low’ to 0 and ‘high’ to the end of the row. If we encounter a 0, we move ‘low’ to the right; if we encounter a 1, we move ‘high’ to the left. Eventually, when ‘low’ and ‘high’ cross each other, ‘low’ will point to the first occurrence of 1, and ‘high’ will point to the last occurrence of 0. We then subtract ‘low’ from the row length and return the total. This gives us the count of 1’s in the row.

We can also use the lower bound (x) or upper bound (x) approach to achieve the same result. In both cases, we need to provide an additional number, which is x = 1 for the lower bound and x = 0 for the upper bound. (link)

class Solution {
    public int rowWithMax1s(int arr[][]) {

        int ansRow = -1;
        int maxOnesGlobal = 0;

        for(int i=0; i<arr.length; i++){
            int maxOnes = getTotalOnes(arr[i]);
            if(maxOnesGlobal<maxOnes){
                maxOnesGlobal = maxOnes;
                ansRow = i;
            }
        }

        return ansRow;
    }

    private int getTotalOnes(int row[]){
        int low = 0;
        int high = row.length-1;

        while(low<=high){
            int mid = (low+high)/2;

            if(row[mid]==0){
                low = mid+1;
            }
            else{
                high = mid-1;
            }
        }
        return row.length-low;
    }
}