# Smallest submatrix required to be removed such that sum of the remaining matrix is divisible by K

• Last Updated : 18 May, 2021

Given a 2D matrix mat[][] of size N * M and a positive integer K, the task is to find the area of the smallest rectangular submatrix that is required to be removed such that the sum of the remaining elements in the matrix is divisible by K.

Examples:

Input: mat[][] = { {6, 2, 6}, {3, 2, 8}, {2, 5, 3} }, K = 3
Output:
Explanation:
Remove the sub-matrix { mat[1][1], mat[2][1] } from the given matrix.
Since the sum of the remaining matrix is equal to 30 which is divisible by K(=3). Therefore, the required output is 1 * 2 = 2.

Input: mat[][] = { {16, 2, 6, 13}, {33, 21, 8, 8}, {31, 5, 3, 11} }, K = 15
Output: 3

Approach: Follow the steps given below to solve the problem:

• Initialize a variable, say S to store the sum of all elements of the given matrix.
• Initialize a variable, say min_area to store the smallest area that needs to be removed such that the sum of the remaining matrix elements is divisible by K.
• Initialize two variables, say left and right to store the leftmost column and rightmost column of each submatrix respectively.
• Initialize an array, say PrefixRowSum[N], where PrefixRowSum[i] stores the sum of all the elements of the submatrix whose top-most left element is (0, left) and bottom-most right element is (i, right) over all possible values of left and right.
• Iterate over all possible values of left and right and find the length of the smallest subarray needs to be deleted to make the sum of the remaining elements of PrefixRowSum[] equal to (S % K) and update min_area
• Finally, print the value of min_area.

Below is the implementation of the above approach:

## C++

 `// C++ program to implement` `// the above approach`   `#include ` `using` `namespace` `std;`   `// Function to find the length of the` `// smallest subarray to be removed such` `// that sum of elements is equal to S % K` `int` `removeSmallestSubarray(``int` `arr[], ``int` `S,` `                              ``int` `n, ``int` `k)` `{` `    `  `    ``// Remainder when total_sum` `    ``// is divided by K` `    ``int` `target_remainder` `        ``= S % k;` `        `  `        `  `    ``// Stores curr_remainder and the` `    ``// most recent index at which` `    ``// curr_remainder has occured` `    ``unordered_map<``int``, ``int``> map1;` `    ``map1[0] = -1;` ` `  `    ``int` `curr_remainder = 0;` ` `  `    ``// Stores required answer` `    ``int` `res = INT_MAX;` ` `  `    ``for` `(``int` `i = 0; i < n; i++) {` ` `  `        ``// Add current element to` `        ``// curr_sum and take mod` `        ``curr_remainder = (curr_remainder` `                          ``+ arr[i] + k)` `                         ``% k;` ` `  `        ``// Update current ` `        ``// remainder index` `        ``map1[curr_remainder] = i;` ` `  `        ``int` `mod` `            ``= (curr_remainder` `               ``- target_remainder` `               ``+ k)` `              ``% k;` ` `  `        ``// If mod already exists in map` `        ``// the subarray exists` `        ``if` `(map1.find(mod) != ` `                        ``map1.end()) {` `            `  `            `  `            ``// Update res` `            ``res = min(res, i - map1[mod]);` `        ``}` `    ``}` ` `  `    ``// If not possible` `    ``if` `(res == INT_MAX || res == n) {` `        ``res = -1;` `    ``}` ` `  `    ``// Return the result` `    ``return` `res;` `}`   `// Function to find the smallest submatrix` `// rqured to be deleted to make the sum` `// of the matrix divisible by K ` `int` `smstSubmatDeleted(vector > &mat, ` `                        ``int` `N, ``int` `M, ``int` `K)` `{`   `    ``// Stores the sum of` `    ``// element of the matrix` `    ``int` `S = 0;`   `    ``// Traverse the matrix mat[][]` `    ``for` `(``int` `i = 0; i < N; i++) {` `        ``for` `(``int` `j = 0; j < M; j++)`   `        ``// Update S` `        ``S += mat[i][j];` `    ``}` `    `  `    ``// Stores smallest area need to be ` `    ``// deleted to get sum divisible by K` `    ``int` `min_area = N * M;` `    `  `    ``// Stores leftmost column` `    ``// of each matrix` `    ``int` `left = 0;` `    `  `    ``// Stores rightmost column` `    ``// of each matrix` `    ``int` `right = 0;` `    `  `    `  `    ``// Stores number of coulmns` `    ``// deleted of a matrix` `    ``int` `width;`   `    ``// Store area of the deleted matrix` `    ``int` `area;`   `    ``// prefixRowSum[i]: Store sum of sub matrix` `    ``// whose topmost left and bottommost right` `    ``// position is (0, left) (i, right)` `    ``int` `prefixRowSum[N];`   `    `  `    ``// Iterate over all possible values` `    ``// of (left, right)` `    ``for` `(left = 0; left < M; left++) {` `        `  `        ``// Initialize all possible values` `        ``// of prefixRowSum[] to 0` `        ``memset``(prefixRowSum, 0, ` `                   ``sizeof``(prefixRowSum));`   `        ``for` `(right = left; right < M; right++) {` `            `  `            ``// Traverse each row from ` `            ``// left to right column` `            ``for` `(``int` `i = 0; i < N; i++) {` `                `  `                ``// Update row_sum[i];` `                ``prefixRowSum[i] ` `                      ``+= mat[i][right];` `                `  `            ``}` `            `  `            `  `            ``// Update width` `            ``width = removeSmallestSubarray(` `                     ``prefixRowSum, S, N, K);` `                                `  `                                `  `            ``// If no submatrix of the length ` `            ``// (right  - left + 1) found to get` `            ``// the required output` `            ``if` `(width != -1) {` `                `  `                `  `                ``// Update area` `                ``area = (right - left + 1) ` `                                  ``* (width);` `                `  `                `  `                ``// If area is less than min_area` `                ``if` `(area < min_area) {` `                    `  `                    ``// Update min_area` `                    ``min_area = area;` `                ``}` `            ``}` `        ``}` `    ``}` `    ``return` `min_area;` `    `  `}`   `// Driver Code   ` `int` `main()` `{`   `    ``vector > mat` `                        ``= { { 6, 2, 6 }, ` `                            ``{ 3, 2, 8 }, ` `                            ``{ 2, 5, 3 } };` `                            `  `    ``int` `K = 3;` `    `  `    ``// Stores number of rows ` `    ``// in the matrix` `    ``int` `N = mat.size();` `    `  `    `  `    ``// Stores number of column ` `    ``// in the matrix` `    ``int` `M = mat[0].size();` `   `  `    ``cout<< smstSubmatDeleted(mat, N, M, K);` `    ``return` `0;` `}`

## Java

 `// Java program to implement` `// the above approach` `import` `java.util.*;` `class` `GFG{`   `// Function to find the length of the` `// smallest subarray to be removed such` `// that sum of elements is equal to S % K` `static` `int` `removeSmallestSubarray(``int` `arr[], ``int` `S,` `                                  ``int` `n, ``int` `k)` `{    ` `  ``// Remainder when total_sum` `  ``// is divided by K` `  ``int` `target_remainder = S % k;`   `  ``// Stores curr_remainder and the` `  ``// most recent index at which` `  ``// curr_remainder has occured` `  ``HashMap map1 = ` `          ``new` `HashMap<>();`   `  ``map1.put(``0``, -``1``);` `  ``int` `curr_remainder = ``0``;`   `  ``// Stores required answer` `  ``int` `res = Integer.MAX_VALUE;`   `  ``for` `(``int` `i = ``0``; i < n; i++) ` `  ``{` `    ``// Add current element to` `    ``// curr_sum and take mod` `    ``curr_remainder = (curr_remainder + ` `                      ``arr[i] + k) % k;`   `    ``// Update current ` `    ``// remainder index` `    ``map1.put(curr_remainder, i);`   `    ``int` `mod = (curr_remainder - ` `               ``target_remainder + ` `               ``k) % k;`   `    ``// If mod already exists in map` `    ``// the subarray exists` `    ``if` `(map1.containsKey(mod)) ` `    ``{` `      ``// Update res` `      ``res = Math.min(res, i - ` `                     ``map1.get(mod));` `    ``}` `  ``}`   `  ``// If not possible` `  ``if` `(res == Integer.MAX_VALUE || ` `      ``res == n) ` `  ``{` `    ``res = -``1``;` `  ``}`   `  ``// Return the result` `  ``return` `res;` `}`   `// Function to find the smallest submatrix` `// rqured to be deleted to make the sum` `// of the matrix divisible by K ` `static` `int` `smstSubmatDeleted(``int``[][]mat, ` `                             ``int` `N, ``int` `M, ` `                             ``int` `K)` `{` `  ``// Stores the sum of` `  ``// element of the matrix` `  ``int` `S = ``0``;`   `  ``// Traverse the matrix mat[][]` `  ``for` `(``int` `i = ``0``; i < N; i++) ` `  ``{` `    ``for` `(``int` `j = ``0``; j < M; j++)`   `      ``// Update S` `      ``S += mat[i][j];` `  ``}`   `  ``// Stores smallest area need ` `  ``// to be deleted to get sum ` `  ``// divisible by K` `  ``int` `min_area = N * M;`   `  ``// Stores leftmost column` `  ``// of each matrix` `  ``int` `left = ``0``;`   `  ``// Stores rightmost column` `  ``// of each matrix` `  ``int` `right = ``0``;`   `  ``// Stores number of coulmns` `  ``// deleted of a matrix` `  ``int` `width;`   `  ``// Store area of the deleted` `  ``// matrix` `  ``int` `area;`   `  ``// prefixRowSum[i]: Store sum ` `  ``// of sub matrix whose topmost ` `  ``// left and bottommost right` `  ``// position is (0, left) (i, right)` `  ``int` `[]prefixRowSum = ``new` `int``[N];`   `  ``// Iterate over all possible ` `  ``// values of (left, right)` `  ``for` `(left = ``0``; left < M; left++) ` `  ``{` `    ``// Initialize all possible` `    ``// values of prefixRowSum[] ` `    ``// to 0` `    ``Arrays.fill(prefixRowSum, ``0``);`   `    ``for` `(right = left; ` `         ``right < M; right++) ` `    ``{` `      ``// Traverse each row from ` `      ``// left to right column` `      ``for` `(``int` `i = ``0``; i < N; i++) ` `      ``{` `        ``// Update row_sum[i];` `        ``prefixRowSum[i] += ` `        ``mat[i][right];` `      ``}`   `      ``// Update width` `      ``width = removeSmallestSubarray(` `              ``prefixRowSum, S, N, K);`   `      ``// If no submatrix of the ` `      ``// length (right  - left + 1) ` `      ``// found to get the required ` `      ``// output` `      ``if` `(width != -``1``) ` `      ``{` `        ``// Update area` `        ``area = (right - left + ``1``) * ` `               ``(width);`   `        ``// If area is less than ` `        ``// min_area` `        ``if` `(area < min_area) ` `        ``{` `          ``// Update min_area` `          ``min_area = area;` `        ``}` `      ``}` `    ``}` `  ``}` `  ``return` `min_area;` `}`   `// Driver Code   ` `public` `static` `void` `main(String[] args)` `{` `  ``int``[][] mat = {{``6``, ``2``, ``6``}, ` `                 ``{``3``, ``2``, ``8``}, ` `                 ``{``2``, ``5``, ``3``}};`   `  ``int` `K = ``3``;`   `  ``// Stores number of rows ` `  ``// in the matrix` `  ``int` `N = mat.length;`   `  ``// Stores number of column ` `  ``// in the matrix` `  ``int` `M = mat[``0``].length;`   `  ``System.out.print(` `  ``smstSubmatDeleted(mat, N,` `                    ``M, K));` `}` `}`   `// This code is contributed by Rajput-Ji`

## Python3

 `# Python3 program to implement` `# the above approach` `import` `sys`   `# Function to find the length of the` `# smallest subarray to be removed such` `# that sum of elements is equal to S % K` `def` `removeSmallestSubarray(arr, S, n, k):` `    `  `    ``# Remainder when total_sum` `    ``# is divided by K` `    ``target_remainder ``=` `S ``%` `k` `    `  `    ``# Stores curr_remainder and the` `    ``# most recent index at which` `    ``# curr_remainder has occured` `    ``map1 ``=` `{}` `    ``map1[``0``] ``=` `-``1`   `    ``curr_remainder ``=` `0`   `    ``# Stores required answer` `    ``res ``=` `sys.maxsize`   `    ``for` `i ``in` `range``(n):` `        `  `        ``# Add current element to` `        ``# curr_sum and take mod` `        ``curr_remainder ``=` `(curr_remainder ``+` `                          ``arr[i] ``+` `k) ``%` `k` `                          `  `        ``# Update current` `        ``# remainder index` `        ``map1[curr_remainder] ``=` `i`   `        ``mod ``=` `(curr_remainder ``-` `             ``target_remainder ``+` `k) ``%` `k` `             `  `        ``# If mod already exists in map` `        ``# the subarray exists` `        ``if` `(mod ``in` `map1):` `            `  `            ``# Update res` `            ``res ``=` `min``(res, i ``-` `map1[mod])` `            `  `    ``# If not possible` `    ``if` `(res ``=``=` `sys.maxsize ``or` `res ``=``=` `n):` `        ``res ``=` `-``1` `        `  `    ``# Return the result` `    ``return` `res` `    `  `# Function to find the smallest submatrix` `# rqured to be deleted to make the sum` `# of the matrix divisible by K` `def` `smstSubmatDeleted(mat, N, M, K):` `    `  `    ``# Stores the sum of` `    ``# element of the matrix` `    ``S ``=` `0` `    `  `    ``# Traverse the matrix mat[][]` `    ``for` `i ``in` `range``(N):` `        ``for` `j ``in` `range``(M):`   `        ``# Update S` `            ``S ``+``=` `mat[i][j]`   `    ``# Stores smallest area need to be` `    ``# deleted to get sum divisible by K` `    ``min_area ``=` `N ``*` `M`   `    ``# Stores leftmost column` `    ``# of each matrix` `    ``left ``=` `0`   `    ``# Stores rightmost column` `    ``# of each matrix` `    ``right ``=` `0` `    `  `    ``# Stores number of coulmns` `    ``# deleted of a matrix` `    ``width ``=` `0` `    `  `    ``# Store area of the deleted matrix` `    ``area ``=` `0` `    `  `    ``# prefixRowSum[i]: Store sum of sub matrix` `    ``# whose topmost left and bottommost right` `    ``# position is (0, left) (i, right)` `    ``prefixRowSm ``=` `[``0``] ``*` `N` `    `  `    ``# Iterate over all possible values` `    ``# of (left, right)` `    ``for` `left ``in` `range``(M):` `        `  `        ``# Initialize all possible values` `        ``# of prefixRowSum[] to 0` `        ``prefixRowSum ``=` `[``0``] ``*` `N` `        `  `        ``for` `right ``in` `range``(left, M):` `            `  `            ``# Traverse each row from` `            ``# left to right column` `            ``for` `i ``in` `range``(N):` `                `  `                ``# Update row_sum[i]` `                ``prefixRowSum[i] ``+``=` `mat[i][right]` `                `  `            ``# Update width` `            ``width ``=` `removeSmallestSubarray(` `                ``prefixRowSum, S, N, K)` `                `  `            ``# If no submatrix of the length` `            ``# (right  - left + 1) found to get` `            ``# the required output` `            ``if` `(width !``=` `-``1``):` `                `  `                ``# Update area` `                ``area ``=` `(right ``-` `left ``+` `1``) ``*` `(width)` `                `  `                ``# If area is less than min_area` `                ``if` `(area < min_area):` `                    `  `                    ``# Update min_area` `                    ``min_area ``=` `area` `                    `  `    ``return` `min_area`   `# Driver Code` `if` `__name__ ``=``=` `'__main__'``:` `    `  `    ``mat ``=` `[ [ ``6``, ``2``, ``6` `],` `            ``[ ``3``, ``2``, ``8` `],` `            ``[ ``2``, ``5``, ``3` `] ]`   `    ``K ``=` `3`   `    ``# Stores number of rows` `    ``# in the matrix` `    ``N ``=` `len``(mat)` `    `  `    ``# Stores number of column` `    ``# in the matrix` `    ``M ``=` `len``(mat[``0``])` `    `  `    ``print``(smstSubmatDeleted(mat, N, M, K))`   `# This code is contributed by mohit kumar 29`

## C#

 `// C# program to implement` `// the above approach` `using` `System;` `using` `System.Collections.Generic;`   `class` `GFG{`   `// Function to find the length of the` `// smallest subarray to be removed such` `// that sum of elements is equal to S % K` `static` `int` `removeSmallestSubarray(``int` `[]arr, ``int` `S,` `                                  ``int` `n, ``int` `k)` `{ ` `  `  `  ``// Remainder when total_sum` `  ``// is divided by K` `  ``int` `target_remainder = S % k;`   `  ``// Stores curr_remainder and the` `  ``// most recent index at which` `  ``// curr_remainder has occured` `  ``Dictionary<``int``,` `             ``int``> map1 = ``new` `Dictionary<``int``,` `                                        ``int``>();` `  `  `  ``map1.Add(0, -1);` `  ``int` `curr_remainder = 0;`   `  ``// Stores required answer` `  ``int` `res = ``int``.MaxValue;`   `  ``for``(``int` `i = 0; i < n; i++) ` `  ``{` `    `  `    ``// Add current element to` `    ``// curr_sum and take mod` `    ``curr_remainder = (curr_remainder + ` `                      ``arr[i] + k) % k;`   `    ``// Update current ` `    ``// remainder index` `    ``map1[curr_remainder]=  i;`   `    ``int` `mod = (curr_remainder - ` `               ``target_remainder + ` `               ``k) % k;`   `    ``// If mod already exists in map` `    ``// the subarray exists` `    ``if` `(map1.ContainsKey(mod)) ` `    ``{` `      `  `      ``// Update res` `      ``res = Math.Min(res, i - ` `                     ``map1[mod]);` `    ``}` `  ``}`   `  ``// If not possible` `  ``if` `(res == ``int``.MaxValue || ` `      ``res == n) ` `  ``{` `    ``res = -1;` `  ``}`   `  ``// Return the result` `  ``return` `res;` `}`   `// Function to find the smallest submatrix` `// rqured to be deleted to make the sum` `// of the matrix divisible by K ` `static` `int` `smstSubmatDeleted(``int``[,]mat, ` `                             ``int` `N, ``int` `M, ` `                             ``int` `K)` `{` `  `  `  ``// Stores the sum of` `  ``// element of the matrix` `  ``int` `S = 0;`   `  ``// Traverse the matrix [,]mat` `  ``for``(``int` `i = 0; i < N; i++) ` `  ``{` `    ``for``(``int` `j = 0; j < M; j++)`   `      ``// Update S` `      ``S += mat[i,j];` `  ``}`   `  ``// Stores smallest area need ` `  ``// to be deleted to get sum ` `  ``// divisible by K` `  ``int` `min_area = N * M;`   `  ``// Stores leftmost column` `  ``// of each matrix` `  ``int` `left = 0;`   `  ``// Stores rightmost column` `  ``// of each matrix` `  ``int` `right = 0;`   `  ``// Stores number of coulmns` `  ``// deleted of a matrix` `  ``int` `width;`   `  ``// Store area of the deleted` `  ``// matrix` `  ``int` `area;`   `  ``// prefixRowSum[i]: Store sum ` `  ``// of sub matrix whose topmost ` `  ``// left and bottommost right` `  ``// position is (0, left) (i, right)` `  ``int` `[]prefixRowSum = ``new` `int``[N];`   `  ``// Iterate over all possible ` `  ``// values of (left, right)` `  ``for``(left = 0; left < M; left++) ` `  ``{` `    `  `    ``// Initialize all possible` `    ``// values of prefixRowSum[] ` `    ``// to 0` `    ``for``(``int` `i = 0; i < prefixRowSum.Length; i++)` `      ``prefixRowSum[i] = 0;`   `    ``for``(right = left; ` `        ``right < M; right++) ` `    ``{` `      `  `      ``// Traverse each row from ` `      ``// left to right column` `      ``for``(``int` `i = 0; i < N; i++) ` `      ``{` `        `  `        ``// Update row_sum[i];` `        ``prefixRowSum[i] += mat[i, right];` `      ``}`   `      ``// Update width` `      ``width = removeSmallestSubarray(` `              ``prefixRowSum, S, N, K);`   `      ``// If no submatrix of the ` `      ``// length (right  - left + 1) ` `      ``// found to get the required ` `      ``// output` `      ``if` `(width != -1) ` `      ``{` `        `  `        ``// Update area` `        ``area = (right - left + 1) * ` `               ``(width);`   `        ``// If area is less than ` `        ``// min_area` `        ``if` `(area < min_area) ` `        ``{` `          `  `          ``// Update min_area` `          ``min_area = area;` `        ``}` `      ``}` `    ``}` `  ``}` `  ``return` `min_area;` `}`   `// Driver Code   ` `public` `static` `void` `Main(String[] args)` `{` `  ``int``[,] mat = { { 6, 2, 6 }, ` `                 ``{ 3, 2, 8 }, ` `                 ``{ 2, 5, 3 } };`   `  ``int` `K = 3;`   `  ``// Stores number of rows ` `  ``// in the matrix` `  ``int` `N = mat.GetLength(0);`   `  ``// Stores number of column ` `  ``// in the matrix` `  ``int` `M = mat.GetLength(1);` `  ``Console.Write(` `  ``smstSubmatDeleted(mat, N,` `                    ``M, K));` `}` `}`   `// This code is contributed by shikhasingrajput`

## Javascript

 ``

Output:

`2`

Time Complexity: O(M2*N)
Auxiliary Space: O(N)

My Personal Notes arrow_drop_up
Recommended Articles
Page :