Skip to content
Related Articles

Related Articles

Save Article
Improve Article
Save Article
Like Article

Queries to count minimum flips required to fill a binary submatrix with 0s only

  • Last Updated : 01 Jun, 2021

Given a binary matrix mat[][] of size M * N and Q queries of the form {pi, pj, qi, qj}, the task for each query is to count the number of 0s in the submatrix from the cell (pi, pj) to (qi, qj).

Examples:

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

Input: mat[][] = {{0, 1, 0, 1, 1, 1, 0}, {1, 0, 1, 1, 1, 0, 1}, {1, 1, 0, 0, 1, 1, 0}, {1, 1, 1, 1, 1, 0, 1}, {0, 0, 1, 0, 1, 1, 1}, {1, 1, 0, 1, 1, 0, 1 }}, Q[] = {{0, 1, 3, 2}, {2, 2, 4, 5}, {4, 3, 5, 6}}
Output: 3 4 2
Explanation: 
The submatrix from indices (0, 1) to (3, 2) contains 3 0s. 
The submatrix from indices (2, 2) to (4, 5) contains 4 0s. 
The submatrix from indices (4, 3) to (5, 6) contains 2 0s.



Input: mat[][] = {{0, 1, 0}, {1, 0, 1}}, Q[] = {{0, 0, 2, 2}}
Output: 3

Naive Approach: The simplest approach to solve the problem is to count the number of 0s for each query by iterating the submatrix and print the count for each query. 

Time Complexity: O(M*N*Q)
Auxiliary Space: O(1)

Efficient Approach: To optimize the above approach, the idea is to preprocess the given matrix mat[][]. Create a count matrix, say prefixCnt[M][N], such that prefix_cnt[i][j] stores the count of 0s in the submatrix within indices (0, 0) to (i, j). Follow the steps below to compute prefixCnt[][]:

  • Initialize prefixCnt[i][j] with 1 if mat[i][j] is 0. Otherwise, initialize with 0.
  • Find the prefix sum for each row and column and update the matrix accordingly.

Once, matrix prefixCnt[][] is computed the count of 0s in any sub-matrix can be evaluated in O(1) time. Below is the expression to count the 0s in each submatrix from (pi, pj) to (qi, qj) can be calculated by:

cnt = prefixCnt[qi][qj] – prefixCnt[pi-1][qj] – prefixCnt[qi][pj – 1] + prefixCnt[pi – 1][pj – 1]

Below is the implementation of the above approach:

C++




// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
#define M 6
#define N 7
 
// Function to compute the matrix
// prefixCnt[M][N] from mat[M][N] such
// that prefixCnt[i][j] stores the
// count of 0's from (0, 0) to (i, j)
void preCompute(int mat[M][N],
                int prefixCnt[M][N])
{
    for (int i = 0; i < M; i++) {
 
        for (int j = 0; j < N; j++) {
 
            // Initialize prefixCnt[i][j]
            // with 1 if mat[i][j] is 0
            if (mat[i][j] == 0) {
                prefixCnt[i][j] = 1;
            }
 
            // Otherwise, assign with 0
            else {
                prefixCnt[i][j] = 0;
            }
        }
    }
 
    // Calculate prefix sum for each row
    for (int i = 0; i < M; i++)
        for (int j = 1; j < N; j++)
            prefixCnt[i][j] += prefixCnt[i][j - 1];
 
    // Calculate prefix sum for each column
    for (int i = 1; i < M; i++)
        for (int j = 0; j < N; j++)
            prefixCnt[i][j] += prefixCnt[i - 1][j];
}
 
// Function to compute count of 0's
// in submatrix from (pi, pj) to
// (qi, qj) from prefixCnt[M][N]
int countQuery(int prefixCnt[M][N],
               int pi, int pj,
               int qi, int qj)
{
    // Initialize that count of 0's
    // in the sub-matrix within
    // indices (0, 0) to (qi, qj)
    int cnt = prefixCnt[qi][qj];
 
    // Subtract count of 0's within
    // indices (0, 0) and (pi-1, qj)
    if (pi > 0)
        cnt -= prefixCnt[pi - 1][qj];
 
    // Subtract count of 0's within
    // indices (0, 0) and (qi, pj-1)
    if (pj > 0)
        cnt -= prefixCnt[qi][pj - 1];
 
    // Add prefixCnt[pi - 1][pj - 1]
    // because its value has been added
    // once but subtracted twice
    if (pi > 0 && pj > 0)
        cnt += prefixCnt[pi - 1][pj - 1];
 
    return cnt;
}
 
// Function to count the 0s in the
// each given submatrix
void count0s(int mat[M][N], int Q[][4],
             int sizeQ)
{
 
    // Stores the prefix sum of each
    // row and column
    int prefixCnt[M][N];
 
    // Compute matrix prefixCnt[][]
    preCompute(mat, prefixCnt);
 
    for (int i = 0; i < sizeQ; i++) {
 
        // Function Call for each query
        cout << countQuery(prefixCnt, Q[i][0],
                           Q[i][1], Q[i][2],
                           Q[i][3])
             << ' ';
    }
}
 
// Driver Code
int main()
{
    // Given matrix
    int mat[M][N] = {
        { 0, 1, 0, 1, 1, 1, 0 },
        { 1, 0, 1, 1, 1, 0, 1 },
        { 1, 1, 0, 0, 1, 1, 0 },
        { 1, 1, 1, 1, 1, 0, 1 },
        { 0, 0, 1, 0, 1, 1, 1 },
        { 1, 1, 0, 1, 1, 0, 1 }
    };
 
    int Q[][4] = { { 0, 1, 3, 2 },
                   { 2, 2, 4, 5 },
                   { 4, 3, 5, 6 } };
 
    int sizeQ = sizeof(Q) / sizeof(Q[0]);
 
    // Function Call
    count0s(mat, Q, sizeQ);
 
    return 0;
}

Java




// Java program for the above approach
class GFG{
     
final static int M = 6;
final static int N  = 7;
 
// Function to compute the matrix
// prefixCnt[M][N] from mat[M][N] such
// that prefixCnt[i][j] stores the
// count of 0's from (0, 0) to (i, j)
static void preCompute(int mat[][], int prefixCnt[][])
{
    for(int i = 0; i < M; i++)
    {
        for(int j = 0; j < N; j++)
        {
             
            // Initialize prefixCnt[i][j]
            // with 1 if mat[i][j] is 0
            if (mat[i][j] == 0)
            {
                prefixCnt[i][j] = 1;
            }
 
            // Otherwise, assign with 0
            else
            {
                prefixCnt[i][j] = 0;
            }
        }
    }
 
    // Calculate prefix sum for each row
    for(int i = 0; i < M; i++)
        for(int j = 1; j < N; j++)
            prefixCnt[i][j] += prefixCnt[i][j - 1];
 
    // Calculate prefix sum for each column
    for(int i = 1; i < M; i++)
        for(int j = 0; j < N; j++)
            prefixCnt[i][j] += prefixCnt[i - 1][j];
}
 
// Function to compute count of 0's
// in submatrix from (pi, pj) to
// (qi, qj) from prefixCnt[M][N]
static int countQuery(int prefixCnt[][],
                      int pi, int pj,
                      int qi, int qj)
{
     
    // Initialize that count of 0's
    // in the sub-matrix within
    // indices (0, 0) to (qi, qj)
    int cnt = prefixCnt[qi][qj];
     
    // Subtract count of 0's within
    // indices (0, 0) and (pi-1, qj)
    if (pi > 0)
        cnt -= prefixCnt[pi - 1][qj];
 
    // Subtract count of 0's within
    // indices (0, 0) and (qi, pj-1)
    if (pj > 0)
        cnt -= prefixCnt[qi][pj - 1];
 
    // Add prefixCnt[pi - 1][pj - 1]
    // because its value has been added;
    // once but subtracted twice
    if (pi > 0 && pj > 0)
        cnt += prefixCnt[pi - 1][pj - 1];
 
    return cnt;
}
 
// Function to count the 0s in the
// each given submatrix
static void count0s(int mat[][], int Q[][],
                    int sizeQ)
{
     
    // Stores the prefix sum of each
    // row and column
    int prefixCnt[][] = new int[M][N];
     
    // Compute matrix prefixCnt[][]
    preCompute(mat, prefixCnt);
 
    for(int i = 0; i < sizeQ; i++)
    {
         
        // Function Call for each query
        System.out.print(countQuery(prefixCnt, Q[i][0],
                                               Q[i][1],
                                               Q[i][2],
                                               Q[i][3]) + " ");
    }
}
 
// Driver Code
public static void main (String[] args)
{
     
    // Given matrix
    int mat[][] = { { 0, 1, 0, 1, 1, 1, 0 },
                    { 1, 0, 1, 1, 1, 0, 1 },
                    { 1, 1, 0, 0, 1, 1, 0 },
                    { 1, 1, 1, 1, 1, 0, 1 },
                    { 0, 0, 1, 0, 1, 1, 1 },
                    { 1, 1, 0, 1, 1, 0, 1 } };
 
    int Q[][] = { { 0, 1, 3, 2 },
                  { 2, 2, 4, 5 },
                  { 4, 3, 5, 6 } };
 
    int sizeQ = Q.length;
 
    // Function Call
    count0s(mat, Q, sizeQ);
}
}
 
// This code is contributed by AnkThon

Python3




# Python3 program for the above approach
 
M = 6
N = 7
 
# Function to compute the matrix
# prefixCnt[M][N] from mat[M][N] such
# that prefixCnt[i][j] stores the
# count of 0's from (0, 0) to (i, j)
def preCompute(mat, prefixCnt):
    for i in range(M):
 
        for j in range(N):
 
            # Initialize prefixCnt[i][j]
            # with 1 if mat[i][j] is 0
            if (mat[i][j] == 0):
                prefixCnt[i][j] = 1
             
            # Otherwise, assign with 0
            else:
                prefixCnt[i][j] = 0
 
    # Calculate prefix sum for each row
    for i in range(M):
        for j in range(1, N):
            prefixCnt[i][j] += prefixCnt[i][j - 1]
 
    # Calculate prefix sum for each column
    for i in range(1, M):
        for j in range(N):
            prefixCnt[i][j] += prefixCnt[i - 1][j]
    return prefixCnt
 
# Function to compute count of 0's
# in submatrix from (pi, pj) to
# (qi, qj) from prefixCnt[M][N]
def countQuery(prefixCnt, pi, pj, qi, qj):
     
    # Initialize that count of 0's
    # in the sub-matrix within
    # indices (0, 0) to (qi, qj)
    cnt = prefixCnt[qi][qj]
 
    # Subtract count of 0's within
    # indices (0, 0) and (pi-1, qj)
    if (pi > 0):
        cnt -= prefixCnt[pi - 1][qj]
 
    # Subtract count of 0's within
    # indices (0, 0) and (qi, pj-1)
    if (pj > 0):
        cnt -= prefixCnt[qi][pj - 1]
 
    # Add prefixCnt[pi - 1][pj - 1]
    # because its value has been added
    # once but subtracted twice
    if (pi > 0 and pj > 0):
        cnt += prefixCnt[pi - 1][pj - 1]
 
    return cnt
 
# Function to count the 0s in the
# each given submatrix
def count0s(mat, Q, sizeQ):
 
    # Stores the prefix sum of each
    # row and column
    prefixCnt = [[ 0 for i in range(N)] for i in range(M)]
 
    # Compute matrix prefixCnt[][]
    prefixCnt = preCompute(mat, prefixCnt)
 
    for i in range(sizeQ):
 
        # Function Call for each query
        print(countQuery(prefixCnt, Q[i][0], Q[i][1], Q[i][2], Q[i][3]), end=" ")
 
# Driver Code
if __name__ == '__main__':
     
    # Given matrix
    mat = [[ 0, 1, 0, 1, 1, 1, 0 ],
        [ 1, 0, 1, 1, 1, 0, 1 ],
        [ 1, 1, 0, 0, 1, 1, 0 ],
        [ 1, 1, 1, 1, 1, 0, 1 ],
        [ 0, 0, 1, 0, 1, 1, 1 ],
        [ 1, 1, 0, 1, 1, 0, 1 ] ]
 
    Q= [ [ 0, 1, 3, 2 ],
        [ 2, 2, 4, 5 ],
        [ 4, 3, 5, 6 ] ]
 
    sizeQ = len(Q)
 
    # Function Call
    count0s(mat, Q, sizeQ)
 
    # This code is contributed by mohit kumar 29

C#




// C# program for the above approach
using System;
class GFG
{
     
static int M = 6;
static int N  = 7;
 
// Function to compute the matrix
// prefixCnt[M][N] from mat[M][N] such
// that prefixCnt[i][j] stores the
// count of 0's from (0, 0) to (i, j)
static void preCompute(int [,]mat, int [,]prefixCnt)
{
    for(int i = 0; i < M; i++)
    {
        for(int j = 0; j < N; j++)
        {
             
            // Initialize prefixCnt[i][j]
            // with 1 if mat[i,j] is 0
            if (mat[i, j] == 0)
            {
                prefixCnt[i, j] = 1;
            }
 
            // Otherwise, assign with 0
            else
            {
                prefixCnt[i, j] = 0;
            }
        }
    }
 
    // Calculate prefix sum for each row
    for(int i = 0; i < M; i++)
        for(int j = 1; j < N; j++)
            prefixCnt[i, j] += prefixCnt[i, j - 1];
 
    // Calculate prefix sum for each column
    for(int i = 1; i < M; i++)
        for(int j = 0; j < N; j++)
            prefixCnt[i, j] += prefixCnt[i - 1, j];
}
 
// Function to compute count of 0's
// in submatrix from (pi, pj) to
// (qi, qj) from prefixCnt[M][N]
static int countQuery(int [,]prefixCnt,
                      int pi, int pj,
                      int qi, int qj)
{
     
    // Initialize that count of 0's
    // in the sub-matrix within
    // indices (0, 0) to (qi, qj)
    int cnt = prefixCnt[qi, qj];
     
    // Subtract count of 0's within
    // indices (0, 0) and (pi-1, qj)
    if (pi > 0)
        cnt -= prefixCnt[pi - 1, qj];
 
    // Subtract count of 0's within
    // indices (0, 0) and (qi, pj-1)
    if (pj > 0)
        cnt -= prefixCnt[qi, pj - 1];
 
    // Add prefixCnt[pi - 1][pj - 1]
    // because its value has been added;
    // once but subtracted twice
    if (pi > 0 && pj > 0)
        cnt += prefixCnt[pi - 1, pj - 1];
 
    return cnt;
}
 
// Function to count the 0s in the
// each given submatrix
static void count0s(int [,]mat, int [,]Q,
                    int sizeQ)
{
     
    // Stores the prefix sum of each
    // row and column
    int [,]prefixCnt = new int[M, N];
     
    // Compute matrix prefixCnt[,]
    preCompute(mat, prefixCnt);
 
    for(int i = 0; i < sizeQ; i++)
    {
         
        // Function Call for each query
        Console.Write(countQuery(prefixCnt, Q[i, 0],
                                               Q[i, 1],
                                               Q[i, 2],
                                               Q[i, 3]) + " ");
    }
}
 
// Driver Code
public static void Main(string[] args)
{
     
    // Given matrix
    int [,]mat = { { 0, 1, 0, 1, 1, 1, 0 },
                    { 1, 0, 1, 1, 1, 0, 1 },
                    { 1, 1, 0, 0, 1, 1, 0 },
                    { 1, 1, 1, 1, 1, 0, 1 },
                    { 0, 0, 1, 0, 1, 1, 1 },
                    { 1, 1, 0, 1, 1, 0, 1 } };
 
    int [,]Q = { { 0, 1, 3, 2 },
                  { 2, 2, 4, 5 },
                  { 4, 3, 5, 6 } };
 
    int sizeQ = Q.GetLength(0);
 
    // Function Call
    count0s(mat, Q, sizeQ);
}
}
 
// This code is contributed by AnkThon

Javascript




<script>
 
// javascript program of the above approach
 
let M = 6;
let N  = 7;
 
// Function to compute the matrix
// prefixCnt[M][N] from mat[M][N] such
// that prefixCnt[i][j] stores the
// count of 0's from (0, 0) to (i, j)
function preCompute(mat, prefixCnt)
{
    for(let i = 0; i < M; i++)
    {
        for(let j = 0; j < N; j++)
        {
             
            // Initialize prefixCnt[i][j]
            // with 1 if mat[i][j] is 0
            if (mat[i][j] == 0)
            {
                prefixCnt[i][j] = 1;
            }
 
            // Otherwise, assign with 0
            else
            {
                prefixCnt[i][j] = 0;
            }
        }
    }
 
    // Calculate prefix sum for each row
    for(let i = 0; i < M; i++)
        for(let j = 1; j < N; j++)
            prefixCnt[i][j] += prefixCnt[i][j - 1];
 
    // Calculate prefix sum for each column
    for(let i = 1; i < M; i++)
        for(let j = 0; j < N; j++)
            prefixCnt[i][j] += prefixCnt[i - 1][j];
}
 
// Function to compute count of 0's
// in submatrix from (pi, pj) to
// (qi, qj) from prefixCnt[M][N]
function countQuery(prefixCnt,
                      pi, pj,
                      qi, qj)
{
     
    // Initialize that count of 0's
    // in the sub-matrix within
    // indices (0, 0) to (qi, qj)
    let cnt = prefixCnt[qi][qj];
     
    // Subtract count of 0's within
    // indices (0, 0) and (pi-1, qj)
    if (pi > 0)
        cnt -= prefixCnt[pi - 1][qj];
 
    // Subtract count of 0's within
    // indices (0, 0) and (qi, pj-1)
    if (pj > 0)
        cnt -= prefixCnt[qi][pj - 1];
 
    // Add prefixCnt[pi - 1][pj - 1]
    // because its value has been added;
    // once but subtracted twice
    if (pi > 0 && pj > 0)
        cnt += prefixCnt[pi - 1][pj - 1];
 
    return cnt;
}
 
// Function to count the 0s in the
// each given submatrix
function count0s(mat, Q,
                    sizeQ)
{
     
    // Stores the prefix sum of each
    // row and column
    let prefixCnt = new Array(M);
     
    // Loop to create 2D array using 1D array
    for (var i = 0; i < prefixCnt.length; i++) {
        prefixCnt[i] = new Array(2);
    }
     
    // Compute matrix prefixCnt[][]
    preCompute(mat, prefixCnt);
 
    for(let i = 0; i < sizeQ; i++)
    {
         
        // Function Call for each query
        document.write(countQuery(prefixCnt, Q[i][0],
                                               Q[i][1],
                                               Q[i][2],
                                               Q[i][3]) + " ");
    }
}
 
    // Driver Code
     
     // Given matrix
    let mat = [[ 0, 1, 0, 1, 1, 1, 0 ],
                    [ 1, 0, 1, 1, 1, 0, 1 ],
                    [ 1, 1, 0, 0, 1, 1, 0 ],
                    [ 1, 1, 1, 1, 1, 0, 1 ],
                    [ 0, 0, 1, 0, 1, 1, 1 ],
                    [ 1, 1, 0, 1, 1, 0, 1 ]];
 
    let Q = [[ 0, 1, 3, 2 ],
                  [ 2, 2, 4, 5 ],
                  [ 4, 3, 5, 6 ]];
 
    let sizeQ = Q.length;
 
    // Function Call
    count0s(mat, Q, sizeQ);
 
// This code is contributed by target_2.
</script>
Output: 
3 4 2

 

Time Complexity: O(M*N + Q)
Auxiliary Space: O(M*N)




My Personal Notes arrow_drop_up
Recommended Articles
Page :