Get the best out of our app
GFG App
Open App
Browser
Continue

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

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:

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 ` `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

 ``

Output:

`3 4 2`

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

My Personal Notes arrow_drop_up
Similar Reads
Related Tutorials