Find the row with maximum number of 1s

Given a boolean 2D array, where each row is sorted. Find the row with the maximum number of 1s.
Example:

Input matrix
0 1 1 1
0 0 1 1
1 1 1 1  // this row has maximum 1s
0 0 0 0

Output: 2

A simple method is to do a row wise traversal of the matrix, count the number of 1s in each row and compare the count with max. Finally, return the index of row with maximum 1s. The time complexity of this method is O(m*n) where m is number of rows and n is number of columns in matrix.

We can do better. Since each row is sorted, we can use Binary Search to count of 1s in each row. We find the index of first instance of 1 in each row. The count of 1s will be equal to total number of columns minus the index of first 1.

See the following code for implementation of the above approach.

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// CPP program to find the row 
// with maximum number of 1s 
#include <bits/stdc++.h>
using namespace std;
#define R 4 
#define C 4 
  
// Function to find the index of first index 
// of 1 in a boolean array arr[] 
int first(bool arr[], int low, int high) 
    if(high >= low) 
    
        // Get the middle index 
        int mid = low + (high - low)/2; 
      
        // Check if the element at middle index is first 1 
        if ( ( mid == 0 || arr[mid-1] == 0) && arr[mid] == 1) 
            return mid; 
      
        // If the element is 0, recur for right side 
        else if (arr[mid] == 0) 
            return first(arr, (mid + 1), high); 
          
        // If element is not first 1, recur for left side 
        else
            return first(arr, low, (mid -1)); 
    
    return -1; 
  
// Function that returns index of row 
// with maximum number of 1s. 
int rowWithMax1s(bool mat[R][C]) 
    // Initialize max values 
    int max_row_index = 0, max = -1; 
  
    // Traverse for each row and count number of 1s 
    // by finding the index of first 1 
    int i, index; 
    for (i = 0; i < R; i++) 
    
        index = first (mat[i], 0, C-1); 
        if (index != -1 && C-index > max) 
        
            max = C - index; 
            max_row_index = i; 
        
    
  
    return max_row_index; 
  
// Driver Code 
int main() 
    bool mat[R][C] = { {0, 0, 0, 1}, 
                    {0, 1, 1, 1}, 
                    {1, 1, 1, 1}, 
                    {0, 0, 0, 0}}; 
  
    cout << "Index of row with maximum 1s is " << rowWithMax1s(mat); 
  
    return 0; 
  
// This is code is contributed by rathbhupendra

chevron_right


C

filter_none

edit
close

play_arrow

link
brightness_4
code

// C program to find the row
// with maximum number of 1s
#include <stdio.h>
#define R 4
#define C 4
  
// Function to find the index of first index
// of 1 in a boolean array arr[] 
int first(bool arr[], int low, int high)
{
if(high >= low)
{
    // Get the middle index 
    int mid = low + (high - low)/2; 
  
    // Check if the element at middle index is first 1
    if ( ( mid == 0 || arr[mid-1] == 0) && arr[mid] == 1)
    return mid;
  
    // If the element is 0, recur for right side
    else if (arr[mid] == 0)
    return first(arr, (mid + 1), high);
      
    // If element is not first 1, recur for left side
    else 
    return first(arr, low, (mid -1));
}
return -1;
}
  
// Function that returns index of row
// with maximum number of 1s. 
int rowWithMax1s(bool mat[R][C])
{
    // Initialize max values
    int max_row_index = 0, max = -1; 
  
    // Traverse for each row and count number of 1s 
    // by finding the index of first 1
    int i, index;
    for (i = 0; i < R; i++)
    {
    index = first (mat[i], 0, C-1);
    if (index != -1 && C-index > max)
    {
        max = C - index;
        max_row_index = i;
    }
    }
  
    return max_row_index;
}
  
// Driver Code
int main()
{
    bool mat[R][C] = { {0, 0, 0, 1},
                       {0, 1, 1, 1},
                       {1, 1, 1, 1},
                       {0, 0, 0, 0}};
  
    printf("Index of row with maximum 1s is %d "
                                , rowWithMax1s(mat));
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to find the row
// with maximum number of 1s
import java.io.*;
  
class GFG {
    static int R = 4, C = 4;
    // Function to find the index of first index
    // of 1 in a boolean array arr[] 
    static int first(int arr[], int low, int high)
    {
        if (high >= low) {
            // Get the middle index
            int mid = low + (high - low) / 2;
  
            // Check if the element at middle index is first 1
            if ((mid == 0 || (arr[mid - 1] == 0)) && arr[mid] == 1)
                return mid;
  
            // If the element is 0, recur for right side
            else if (arr[mid] == 0)
                return first(arr, (mid + 1), high);
                  
            // If element is not first 1, recur for left side
            else 
                return first(arr, low, (mid - 1));
        }
        return -1;
    }
  
    // Function that returns index of row
    // with maximum number of 1s.
    static int rowWithMax1s(int mat[][])
    {
        // Initialize max values
        int max_row_index = 0, max = -1
  
        // Traverse for each row and count number of 
        // 1s by finding the index of first 1
        int i, index;
        for (i = 0; i < R; i++) {
            index = first(mat[i], 0, C - 1);
            if (index != -1 && C - index > max) {
                max = C - index;
                max_row_index = i;
            }
        }
  
        return max_row_index;
    }
    // Driver Code
    public static void main(String[] args)
    {
        int mat[][] = { { 0, 0, 0, 1 },
                        { 0, 1, 1, 1 },
                        { 1, 1, 1, 1 },
                        { 0, 0, 0, 0 } };
        System.out.println("Index of row with maximum 1s is "
                                            + rowWithMax1s(mat));
    }
}
  
// This code is contributed by 'Gitanjali'.

chevron_right


Python 3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program to find the row
# with maximum number of 1s
  
# Function to find the index
# of first index of 1 in a 
# boolean array arr[] 
def first( arr, low, high):
    if high >= low:
          
        # Get the middle index 
        mid = low + (high - low)//2
  
        # Check if the element at 
        # middle index is first 1
        if (mid == 0 or arr[mid - 1] == 0) and arr[mid] == 1:
            return mid
  
        # If the element is 0, 
        # recur for right side
        elif arr[mid] == 0:
            return first(arr, (mid + 1), high)
      
        # If element is not first 1, 
        # recur for left side
        else:
            return first(arr, low, (mid - 1))
    return -1
  
# Function that returns 
# index of row with maximum 
# number of 1s. 
def rowWithMax1s( mat):
      
    # Initialize max values
    R = len(mat)
    C = len(mat[0])
    max_row_index = 0
    max = -1
      
    # Traverse for each row and 
    # count number of 1s by finding
    #  the index of first 1
    for i in range(0, R):
        index = first (mat[i], 0, C - 1)
        if index != -1 and C - index > max:
            max = C - index
            max_row_index = i
  
    return max_row_index
  
# Driver Code
mat = [[0, 0, 0, 1],
       [0, 1, 1, 1],
       [1, 1, 1, 1],
       [0, 0, 0, 0]]
print ("Index of row with maximum 1s is"
      rowWithMax1s(mat))
  
# This code is contributed 
# by shreyanshi_arun 

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to find the row with maximum
// number of 1s 
using System;
  
class GFG
{
public static int R = 4, C = 4;
  
// Function to find the index of first index 
// of 1 in a boolean array arr[] 
public static int first(int[] arr, 
                        int low, int high)
{
    if (high >= low)
    {
        // Get the middle index 
        int mid = low + (high - low) / 2;
  
        // Check if the element at middle 
        // index is first 1 
        if ((mid == 0 || (arr[mid - 1] == 0)) &&
                          arr[mid] == 1)
        {
            return mid;
        }
  
        // If the element is 0, recur 
        // for right side 
        else if (arr[mid] == 0)
        {
            return first(arr, (mid + 1), high);
        }
  
        // If element is not first 1, recur
        // for left side 
        else
        {
            return first(arr, low, (mid - 1));
        }
    }
    return -1;
}
  
// Function that returns index of row 
// with maximum number of 1s. 
public static int rowWithMax1s(int[][] mat)
{
    // Initialize max values 
    int max_row_index = 0, max = -1;
  
    // Traverse for each row and count number  
    // of 1s by finding the index of first 1 
    int i, index;
    for (i = 0; i < R; i++)
    {
        index = first(mat[i], 0, C - 1);
        if (index != -1 && C - index > max)
        {
            max = C - index;
            max_row_index = i;
        }
    }
  
    return max_row_index;
}
  
// Driver Code 
public static void Main(string[] args)
{
    int[][] mat = new int[][]
    {
        new int[] {0, 0, 0, 1},
        new int[] {0, 1, 1, 1},
        new int[] {1, 1, 1, 1},
        new int[] {0, 0, 0, 0}
    };
    Console.WriteLine("Index of row with maximum 1s is "
                                       rowWithMax1s(mat));
}
}
  
// This code is contributed by Shrikant13

chevron_right


PHP

filter_none

edit
close

play_arrow

link
brightness_4
code

<?php
// PHP program to find the row 
// with maximum number of 1s 
define("R", 4);
define("C", 4); 
  
// Function to find the index of first 
// index of 1 in a boolean array arr[] 
function first($arr, $low, $high
    if($high >= $low
    
        // Get the middle index 
        $mid = $low + intval(($high - $low) / 2); 
      
        // Check if the element at middle 
        // index is first 1 
        if (($mid == 0 || $arr[$mid - 1] == 0) && 
                          $arr[$mid] == 1) 
        return $mid
      
        // If the element is 0, recur for
        // right side 
        else if ($arr[$mid] == 0) 
        return first($arr, ($mid + 1), $high); 
          
        // If element is not first 1, recur 
        // for left side 
        else
        return first($arr, $low, ($mid - 1)); 
    
    return -1; 
  
// Function that returns index of row 
// with maximum number of 1s. 
function rowWithMax1s($mat
      
    // Initialize max values 
    $max_row_index = 0;
    $max = -1; 
  
    // Traverse for each row and count number 
    // of 1s by finding the index of first 1 
      
    for ($i = 0; $i < R; $i++) 
    
    $index = first ($mat[$i], 0, (C - 1)); 
    if ($index != -1 && (C - $index) > $max
    
        $max = C - $index
        $max_row_index = $i
    
    
  
    return $max_row_index
  
// Driver Code 
$mat = array(array(0, 0, 0, 1), 
             array(0, 1, 1, 1), 
             array(1, 1, 1, 1), 
             array(0, 0, 0, 0)); 
  
echo "Index of row with maximum 1s is " .               
                      rowWithMax1s($mat); 
  
// This code is contributed by rathbhupendra
?>

chevron_right



Output:

Index of row with maximum 1s is 2

Time Complexity: O(mLogn) where m is number of rows and n is number of columns in matrix.

The above solution can be optimized further. Instead of doing binary search in every row, we first check whether the row has more 1s than max so far. If the row has more 1s, then only count 1s in the row. Also, to count 1s in a row, we don’t do binary search in complete row, we do search in before the index of last max.

Following is an optimized version of the above solution.

C++

#include
using namespace std;

// The main function that returns index
// of row with maximum number of 1s.
int rowWithMax1s(bool mat[R][C])
{
int i, index;

// Initialize max using values from first row.
int max_row_index = 0;
int max = first(mat[0], 0, C – 1);

// Traverse for each row and count number of 1s
// by finding the index of first 1
for (i = 1; i < R; i++) { // Count 1s in this row only if this row // has more 1s than max so far // Count 1s in this row only if this row // has more 1s than max so far if (max != -1 && mat[i][C - max - 1] == 1) { // Note the optimization here also index = first (mat[i], 0, C - max); if (index != -1 && C - index > max)
{
max = C – index;
max_row_index = i;
}
}
else
{
max = first(mat[i], 0, C – 1);
}
}
return max_row_index;
}

// This code is contributed by rathbhupendra

C

filter_none

edit
close

play_arrow

link
brightness_4
code

// The main function that returns index of row with maximum number of 1s.
int rowWithMax1s(bool mat[R][C])
{
    int i, index;
   
    // Initialize max using values from first row.  
    int max_row_index = 0;
    int max = first(mat[0], 0, C-1);
   
    // Traverse for each row and count number of 1s by finding the index
    // of first 1
    for (i = 1; i < R; i++)
    {
        // Count 1s in this row only if this row has more 1s than
        // max so far
  
        // Count 1s in this row only if this row has more 1s than
        // max so far
        if (max != -1 && mat[i][C-max-1] == 1)
        {
            // Note the optimization here also
            index = first (mat[i], 0, C-max);
   
            if (index != -1 && C-index > max)
            {
                max = C - index;
                max_row_index = i;
            }   
        }
        else {
            max = first(mat[i], 0, C - 1); 
        }   
    }   
    return max_row_index;
}

chevron_right



The worst case time complexity of the above optimized version is also O(mLogn), the will solution work better on average. Thanks to Naveen Kumar Singh for suggesting the above solution.

The worst case of the above solution occurs for a matrix like following.
0 0 0 … 0 1
0 0 0 ..0 1 1
0 … 0 1 1 1
….0 1 1 1 1

Following method works in O(m+n) time complexity in worst case.

Step1: Get the index of first (or leftmost) 1 in the first row.

Step2: Do following for every row after the first row
…IF the element on left of previous leftmost 1 is 0, ignore this row.
…ELSE Move left until a 0 is found. Update the leftmost index to this index and max_row_index to be the current row.

The time complexity is O(m+n) because we can possibly go as far left as we came ahead in the first step.

Following is C++ implementation of this method.

filter_none

edit
close

play_arrow

link
brightness_4
code

// The main function that returns index of row with maximum number of 1s.
int rowWithMax1s(bool mat[R][C])
{
    // Initialize first row as row with max 1s
    int max_row_index = 0;
  
    // The function first() returns index of first 1 in row 0.
    // Use this index to initialize the index of leftmost 1 seen so far
    int j = first(mat[0], 0, C-1);
    if (j == -1) // if 1 is not present in first row
      j = C - 1;
  
    for (int i = 1; i < R; i++)
    {
        // Move left until a 0 is found
        while (j >= 0 && mat[i][j] == 1)
        {
           j = j-1;  // Update the index of leftmost 1 seen so far
           max_row_index = i;  // Update max_row_index
        }
    }
    return max_row_index;
}

chevron_right


Thanks to Tylor, Ankan and Palash for their inputs.

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.



My Personal Notes arrow_drop_up

Improved By : shrikanth13, rathbhupendra