# Find the largest area rectangular sub-matrix whose sum is equal to k

Given a 2D matrix mat[][] and a value k. Find the largest rectangular sub-matrix whose sum is equal to k.

Example:

```Input : mat = { { 1, 7, -6, 5 },
{ -8, 6, 7, -2 },
{ 10, -15, 3, 2 },
{ -5, 2, 0, 9 } }
k = 7

Output : (Top, Left): (0, 1)
(Bottom, Right): (2, 3)
7 -6 5
6 7 -2
-15 3 2
```

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

Naive Approach: Check every possible rectangle in given 2D array having sum equal to ‘k’ and print the largest one. This solution requires 4 nested loops and time complexity of this solution would be O(n^4).

Efficient Approach: Longest sub-array having sum k for 1-D array can be used to reduce the time complexity to O(n^3). The idea is to fix the left and right columns one by one and find the longest sub-array having sum equal to ‘k’ for contiguous rows for every left and right column pair. We basically find top and bottom row numbers (which are part of the largest sub-matrix) for every fixed left and right column pair. To find the top and bottom row numbers, calculate sum of elements in every row from left to right and store these sums in an array say temp[]. So temp[i] indicates sum of elements from left to right in row i. Now, apply Longest sub-array having sum k 1D algorithm on temp[], and get the longest sub-array having sum equal to ‘k’ of temp[]. This length would be the maximum possible length with left and right as boundary columns. Set the ‘top’ and ‘bottom’ row indexes for the left right column pair and calculate the area. In similar manner get the top, bottom, left, right indexes for other sub-matrices having sum equal to ‘k’ and print the one having maximum area.

 `// C++ implementation to find the largest area rectangular ` `// sub-matrix whose sum is equal to k ` `#include ` `using` `namespace` `std; ` ` `  `const` `int` `MAX = 100; ` ` `  `// This function basically finds largest 'k' ` `// sum subarray in arr[0..n-1]. If 'k' sum ` `// doesn't exist, then it returns false. Else ` `// it returns true and sets starting and ` `// ending indexes as start and end. ` `bool` `sumEqualToK(``int` `arr[], ``int``& start, ` `                 ``int``& end, ``int` `n, ``int` `k) ` `{ ` `    ``// unordered_map 'um' implemented ` `    ``// as hash table ` `    ``unordered_map<``int``, ``int``> um; ` `    ``int` `sum = 0, maxLen = 0; ` ` `  `    ``// traverse the given array ` `    ``for` `(``int` `i = 0; i < n; i++) { ` ` `  `        ``// accumulate sum ` `        ``sum += arr[i]; ` ` `  `        ``// when subarray starts from index '0' ` `        ``// update maxLength and start and end points ` `        ``if` `(sum == k) { ` `            ``maxLen = i + 1; ` `            ``start = 0; ` `            ``end = i; ` `        ``} ` ` `  `        ``// make an entry for 'sum' if it is ` `        ``// not present in 'um' ` `        ``if` `(um.find(sum) == um.end()) ` `            ``um[sum] = i; ` ` `  `        ``// check if 'sum-k' is present in 'um' ` `        ``// or not ` `        ``if` `(um.find(sum - k) != um.end()) { ` ` `  `            ``// update maxLength and start and end points ` `            ``if` `(maxLen < (i - um[sum - k])) { ` `                ``maxLen = i - um[sum - k]; ` `                ``start = um[sum - k] + 1; ` `                ``end = i; ` `            ``} ` `        ``} ` `    ``} ` ` `  `    ``// Return true if maximum length is non-zero ` `    ``return` `(maxLen != 0); ` `} ` ` `  `// function to find the largest area rectangular ` `// sub-matrix whose sum is equal to k ` `void` `sumZeroMatrix(``int` `mat[][MAX], ``int` `row, ``int` `col, ``int` `k) ` `{ ` `    ``// Variables to store the temporary values ` `    ``int` `temp[row], area; ` `    ``bool` `sum; ` `    ``int` `up, down; ` ` `  `    ``// Variables to store the final output ` `    ``int` `fup = 0, fdown = 0, fleft = 0, fright = 0; ` `    ``int` `maxArea = INT_MIN; ` ` `  `    ``// Set the left column ` `    ``for` `(``int` `left = 0; left < col; left++) { ` `        ``// Initialize all elements of temp as 0 ` `        ``memset``(temp, 0, ``sizeof``(temp)); ` ` `  `        ``// Set the right column for the left column ` `        ``// set by outer loop ` `        ``for` `(``int` `right = left; right < col; right++) { ` `            ``// Calculate sum between current left ` `            ``// and right column for every row 'i' ` `            ``for` `(``int` `i = 0; i < row; i++) ` `                ``temp[i] += mat[i][right]; ` ` `  `            ``// Find largest subarray with 'k' sum in ` `            ``// temp[]. The sumEqualToK() function also ` `            ``// sets values of 'up' and 'down;'. So ` `            ``// if 'sum' is true then rectangle exists between ` `            ``// (up, left) and (down, right) which are the ` `            ``// boundary values. ` `            ``sum = sumEqualToK(temp, up, down, row, k); ` `            ``area = (down - up + 1) * (right - left + 1); ` ` `  `            ``// Compare no. of elements with previous ` `            ``// no. of elements in sub-Matrix. ` `            ``// If new sub-matrix has more elements ` `            ``// then update maxArea and final boundaries ` `            ``// like fup, fdown, fleft, fright ` `            ``if` `(sum && maxArea < area) { ` `                ``fup = up; ` `                ``fdown = down; ` `                ``fleft = left; ` `                ``fright = right; ` `                ``maxArea = area; ` `            ``} ` `        ``} ` `    ``} ` ` `  `    ``// If there is no change in boundaries ` `    ``// than check if mat[0][0] equals 'k' ` `    ``// If it is not equal to 'k' then print ` `    ``// that no such k-sum sub-matrix exists ` `    ``if` `(fup == 0 && fdown == 0 && fleft == 0 && ` `        ``fright == 0 && mat[0][0] != k) { ` `        ``cout << ``"No sub-matrix with sum "` `<< k << ``" exists"``; ` `        ``return``; ` `    ``} ` ` `  `    ``// Print final values ` ` `  `    ``cout << ``"(Top, Left): "` `         ``<< ``"("` `<< fup << ``", "` `<< fleft ` `         ``<< ``")"` `<< endl; ` ` `  `    ``cout << ``"(Bottom, Right): "` `         ``<< ``"("` `<< fdown << ``", "` `<< fright ` `         ``<< ``")"` `<< endl; ` ` `  `    ``for` `(``int` `j = fup; j <= fdown; j++) { ` `        ``for` `(``int` `i = fleft; i <= fright; i++) ` `            ``cout << mat[j][i] << ``" "``; ` `        ``cout << endl; ` `    ``} ` `} ` ` `  `// Driver program to test above ` `int` `main() ` `{ ` `    ``int` `mat[][MAX] = { { 1, 7, -6, 5 }, ` `                       ``{ -8, 6, 7, -2 }, ` `                       ``{ 10, -15, 3, 2 }, ` `                       ``{ -5, 2, 0, 9 } }; ` ` `  `    ``int` `row = 4, col = 4; ` `    ``int` `k = 7; ` `    ``sumZeroMatrix(mat, row, col, k); ` `    ``return` `0; ` `} `

 `// Java implementation to find  ` `// the largest area rectangular ` `// sub-matrix whose sum is equal to k ` `import` `java.util.*; ` ` `  `class` `GFG ` `{ ` ` `  `static` `int` `MAX = ``100``; ` `static` `int` `start, end; ` ` `  `// This function basically finds largest 'k' ` `// sum subarray in arr[0..n-1]. If 'k' sum ` `// doesn't exist, then it returns false. Else ` `// it returns true and sets starting and ` `// ending indexes as start and end. ` `static` `boolean` `sumEqualToK(``int` `arr[], ``int` `n, ``int` `k) ` `{ ` `    ``// unordered_map 'um' implemented ` `    ``// as hash table ` `    ``HashMap um =  ` `    ``new` `HashMap(); ` `     `  `    ``int` `sum = ``0``, maxLen = ``0``; ` ` `  `    ``// traverse the given array ` `    ``for` `(``int` `i = ``0``; i < n; i++) ` `    ``{ ` ` `  `        ``// accumulate sum ` `        ``sum += arr[i]; ` ` `  `        ``// when subarray starts from index '0' ` `        ``// update maxLength and start and end points ` `        ``if` `(sum == k) ` `        ``{ ` `            ``maxLen = i + ``1``; ` `            ``start = ``0``; ` `            ``end = i; ` `        ``} ` ` `  `        ``// make an entry for 'sum' if it is ` `        ``// not present in 'um' ` `        ``if` `(!um.containsKey(sum)) ` `            ``um.put(sum, i); ` ` `  `        ``// check if 'sum-k' is present in 'um' ` `        ``// or not ` `        ``if` `(um.containsKey(sum - k))  ` `        ``{ ` ` `  `            ``// update maxLength and start and end points ` `            ``if` `(maxLen < (i - um.get(sum - k)))  ` `            ``{ ` `                ``maxLen = i - um.get(sum - k); ` `                ``start = um.get(sum - k) + ``1``; ` `                ``end = i; ` `            ``} ` `        ``} ` `    ``} ` ` `  `    ``// Return true if maximum length is non-zero ` `    ``return` `(maxLen != ``0``); ` `} ` ` `  `// function to find the largest area rectangular ` `// sub-matrix whose sum is equal to k ` `static` `void` `sumZeroMatrix(``int` `mat[][], ``int` `row,  ` `                            ``int` `col, ``int` `k) ` `{ ` `    ``// Variables to store the temporary values ` `    ``int` `[]temp = ``new` `int``[row]; ` `    ``int` `area; ` `    ``boolean` `sum = ``false``; ` ` `  `    ``// Variables to store the final output ` `    ``int` `fup = ``0``, fdown = ``0``, fleft = ``0``, fright = ``0``; ` `    ``int` `maxArea = Integer.MIN_VALUE; ` ` `  `    ``// Set the left column ` `    ``for` `(``int` `left = ``0``; left < col; left++) ` `    ``{ ` `         `  `        ``// Initialize all elements of temp as 0 ` `        ``temp = memset(temp, ``0``); ` `         `  `        ``// Set the right column for the left column ` `        ``// set by outer loop ` `        ``for` `(``int` `right = left; right < col; right++) ` `        ``{ ` `            ``// Calculate sum between current left ` `            ``// and right column for every row 'i' ` `            ``for` `(``int` `i = ``0``; i < row; i++) ` `                ``temp[i] += mat[i][right]; ` ` `  `            ``// Find largest subarray with 'k' sum in ` `            ``// temp[]. The sumEqualToK() function also ` `            ``// sets values of 'up' and 'down;'. So ` `            ``// if 'sum' is true then rectangle exists between ` `            ``// (up, left) and (down, right) which are the ` `            ``// boundary values. ` `            ``sum = sumEqualToK(temp, row, k); ` `            ``area = (end - start + ``1``) * (right - left + ``1``); ` ` `  `            ``// Compare no. of elements with previous ` `            ``// no. of elements in sub-Matrix. ` `            ``// If new sub-matrix has more elements ` `            ``// then update maxArea and final boundaries ` `            ``// like fup, fdown, fleft, fright ` `            ``if` `(sum && maxArea < area)  ` `            ``{ ` `                ``fup = start; ` `                ``fdown = end; ` `                ``fleft = left; ` `                ``fright = right; ` `                ``maxArea = area; ` `            ``} ` `        ``} ` `    ``} ` ` `  `    ``// If there is no change in boundaries ` `    ``// than check if mat[0][0] equals 'k' ` `    ``// If it is not equal to 'k' then print ` `    ``// that no such k-sum sub-matrix exists ` `    ``if` `(fup == ``0` `&& fdown == ``0` `&& fleft == ``0` `&& ` `        ``fright == ``0` `&& mat[``0``][``0``] != k) ` `    ``{ ` `        ``System.out.print(``"No sub-matrix with sum "`  `                        ``+ k + ``" exists"``); ` `        ``return``; ` `    ``} ` ` `  `    ``// Print final values ` `    ``System.out.print(``"(Top, Left): "` `        ``+ ``"("` `+ fup+ ``", "` `+ fleft ` `        ``+ ``")"` `+``"\n"``); ` ` `  `    ``System.out.print(``"(Bottom, Right): "` `        ``+ ``"("` `+ fdown+ ``", "` `+ fright ` `        ``+ ``")"` `+``"\n"``); ` ` `  `    ``for` `(``int` `j = fup; j <= fdown; j++) ` `    ``{ ` `        ``for` `(``int` `i = fleft; i <= fright; i++) ` `            ``System.out.print(mat[j][i] + ``" "``); ` `        ``System.out.println(); ` `    ``} ` `} ` `static` `int``[] memset(``int` `[]arr, ``int` `val) ` `{ ` `    ``for``(``int` `i = ``0``; i < arr.length; i++) ` `        ``arr[i] = val; ` `    ``return` `arr; ` `} ` ` `  `// Driver code ` `public` `static` `void` `main(String[] args) ` `{ ` `    ``int` `mat[][] = { { ``1``, ``7``, -``6``, ``5` `}, ` `                    ``{ -``8``, ``6``, ``7``, -``2` `}, ` `                    ``{ ``10``, -``15``, ``3``, ``2` `}, ` `                    ``{ -``5``, ``2``, ``0``, ``9` `} }; ` ` `  `    ``int` `row = ``4``, col = ``4``; ` `    ``int` `k = ``7``; ` `    ``sumZeroMatrix(mat, row, col, k); ` `} ` `} ` ` `  `// This code is contributed by PrinciRaj1992 `

 `// C# implementation to find  ` `// the largest area rectangular ` `// sub-matrix whose sum is equal to k ` `using` `System; ` `using` `System.Collections.Generic; ` ` `  `class` `GFG ` `{ ` ` `  `static` `int` `MAX = 100; ` `static` `int` `start, end; ` ` `  `// This function basically finds largest 'k' ` `// sum subarray in arr[0..n-1]. If 'k' sum ` `// doesn't exist, then it returns false. Else ` `// it returns true and sets starting and ` `// ending indexes as start and end. ` `static` `bool` `sumEqualToK(``int` `[]arr, ``int` `n, ``int` `k) ` `{ ` `    ``// unordered_map 'um' implemented ` `    ``// as hash table ` `    ``Dictionary<``int``,``int``> um =  ` `    ``new` `Dictionary<``int``,``int``>(); ` `     `  `    ``int` `sum = 0, maxLen = 0; ` ` `  `    ``// traverse the given array ` `    ``for` `(``int` `i = 0; i < n; i++) ` `    ``{ ` ` `  `        ``// accumulate sum ` `        ``sum += arr[i]; ` ` `  `        ``// when subarray starts from index '0' ` `        ``// update maxLength and start and end points ` `        ``if` `(sum == k) ` `        ``{ ` `            ``maxLen = i + 1; ` `            ``start = 0; ` `            ``end = i; ` `        ``} ` ` `  `        ``// make an entry for 'sum' if it is ` `        ``// not present in 'um' ` `        ``if` `(!um.ContainsKey(sum)) ` `            ``um.Add(sum, i); ` ` `  `        ``// check if 'sum-k' is present in 'um' ` `        ``// or not ` `        ``if` `(um.ContainsKey(sum - k))  ` `        ``{ ` ` `  `            ``// update maxLength and start and end points ` `            ``if` `(maxLen < (i - um[sum - k]))  ` `            ``{ ` `                ``maxLen = i - um[sum - k]; ` `                ``start = um[sum - k] + 1; ` `                ``end = i; ` `            ``} ` `        ``} ` `    ``} ` ` `  `    ``// Return true if maximum length is non-zero ` `    ``return` `(maxLen != 0); ` `} ` ` `  `// function to find the largest area rectangular ` `// sub-matrix whose sum is equal to k ` `static` `void` `sumZeroMatrix(``int` `[,]mat, ``int` `row,  ` `                            ``int` `col, ``int` `k) ` `{ ` `    ``// Variables to store the temporary values ` `    ``int` `[]temp = ``new` `int``[row]; ` `    ``int` `area; ` `    ``bool` `sum = ``false``; ` ` `  `    ``// Variables to store the readonly output ` `    ``int` `fup = 0, fdown = 0, fleft = 0, fright = 0; ` `    ``int` `maxArea = ``int``.MinValue; ` ` `  `    ``// Set the left column ` `    ``for` `(``int` `left = 0; left < col; left++) ` `    ``{ ` `         `  `        ``// Initialize all elements of temp as 0 ` `        ``temp = memset(temp, 0); ` `         `  `        ``// Set the right column for the left column ` `        ``// set by outer loop ` `        ``for` `(``int` `right = left; right < col; right++) ` `        ``{ ` `            ``// Calculate sum between current left ` `            ``// and right column for every row 'i' ` `            ``for` `(``int` `i = 0; i < row; i++) ` `                ``temp[i] += mat[i, right]; ` ` `  `            ``// Find largest subarray with 'k' sum in ` `            ``// []temp. The sumEqualToK() function also ` `            ``// sets values of 'up' and 'down;'. So ` `            ``// if 'sum' is true then rectangle exists between ` `            ``// (up, left) and (down, right) which are the ` `            ``// boundary values. ` `            ``sum = sumEqualToK(temp, row, k); ` `            ``area = (end - start + 1) * (right - left + 1); ` ` `  `            ``// Compare no. of elements with previous ` `            ``// no. of elements in sub-Matrix. ` `            ``// If new sub-matrix has more elements ` `            ``// then update maxArea and readonly boundaries ` `            ``// like fup, fdown, fleft, fright ` `            ``if` `(sum && maxArea < area)  ` `            ``{ ` `                ``fup = start; ` `                ``fdown = end; ` `                ``fleft = left; ` `                ``fright = right; ` `                ``maxArea = area; ` `            ``} ` `        ``} ` `    ``} ` ` `  `    ``// If there is no change in boundaries ` `    ``// than check if mat[0,0] equals 'k' ` `    ``// If it is not equal to 'k' then print ` `    ``// that no such k-sum sub-matrix exists ` `    ``if` `(fup == 0 && fdown == 0 && fleft == 0 && ` `        ``fright == 0 && mat[0, 0] != k) ` `    ``{ ` `        ``Console.Write(``"No sub-matrix with sum "` `                        ``+ k + ``" exists"``); ` `        ``return``; ` `    ``} ` ` `  `    ``// Print readonly values ` `    ``Console.Write(``"(Top, Left): "` `        ``+ ``"("` `+ fup+ ``", "` `+ fleft ` `        ``+ ``")"` `+``"\n"``); ` ` `  `    ``Console.Write(``"(Bottom, Right): "` `        ``+ ``"("` `+ fdown+ ``", "` `+ fright ` `        ``+ ``")"` `+``"\n"``); ` ` `  `    ``for` `(``int` `j = fup; j <= fdown; j++) ` `    ``{ ` `        ``for` `(``int` `i = fleft; i <= fright; i++) ` `            ``Console.Write(mat[j, i] + ``" "``); ` `        ``Console.WriteLine(); ` `    ``} ` `} ` `static` `int``[] memset(``int` `[]arr, ``int` `val) ` `{ ` `    ``for``(``int` `i = 0; i < arr.Length; i++) ` `        ``arr[i] = val; ` `    ``return` `arr; ` `} ` ` `  `// Driver code ` `public` `static` `void` `Main(String[] args) ` `{ ` `    ``int` `[,]mat = { { 1, 7, -6, 5 }, ` `                    ``{ -8, 6, 7, -2 }, ` `                    ``{ 10, -15, 3, 2 }, ` `                    ``{ -5, 2, 0, 9 } }; ` ` `  `    ``int` `row = 4, col = 4; ` `    ``int` `k = 7; ` `    ``sumZeroMatrix(mat, row, col, k); ` `} ` `} ` ` `  `// This code is contributed by PrinciRaj1992 `

Output:

```(Top, Left): (0, 1)
(Bottom, Right): (2, 3)
7 -6 5
6 7 -2
-15 3 2
```

Time Complexity: O(n^3).
Auxiliary Space: O(n).

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.

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.

Improved By : princiraj1992

Article Tags :