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
Brute Approach:
The program takes in a matrix of integers and an integer value k as input, and returns the largest submatrix of the matrix whose sum is equal to k.
Algorithm
- Initialize maxSubmatrix to an empty 2D vector and maxSize to 0.
- Loop through all possible starting rows and columns of submatrices (let them be denoted by r and c respectively)
i. Loop through all possible ending rows and columns of submatrices (let them be denoted by rEnd and cEnd respectively) i. Calculate the sum of elements in the current submatrix by looping through its rows and columns ii. If the sum is equal to k and the size of the submatrix is greater than maxSize, update maxSubmatrix to the current submatrix and maxSize to its size
- Return maxSubmatrix
C++
#include <iostream>
#include <vector>
using namespace std;
vector<vector< int >> findLargestSubmatrixWithSumK(vector<vector< int >>& mat, int k) {
int m = mat.size();
int n = mat[0].size();
vector<vector< int >> maxSubmatrix;
int maxSize = 0;
for ( int r = 0; r < m; r++) {
for ( int c = 0; c < n; c++) {
for ( int rEnd = r; rEnd < m; rEnd++) {
for ( int cEnd = c; cEnd < n; cEnd++) {
int submatrixSum = 0;
for ( int i = r; i <= rEnd; i++) {
for ( int j = c; j <= cEnd; j++) {
submatrixSum += mat[i][j];
}
}
if (submatrixSum == k && (rEnd - r + 1) * (cEnd - c + 1) > maxSize) {
maxSubmatrix.clear();
for ( int i = r; i <= rEnd; i++) {
vector< int > row(mat[i].begin() + c, mat[i].begin() + cEnd + 1);
maxSubmatrix.push_back(row);
}
maxSize = (rEnd - r + 1) * (cEnd - c + 1);
}
}
}
}
}
return maxSubmatrix;
}
int main() {
vector<vector< int >> mat = {{ 1, 7, -6, 5 },
{ -8, 6, 7, -2 },
{ 10, -15, 3, 2 },
{ -5, 2, 0, 9 }};
int k = 7;
vector<vector< int >> largestSubmatrix = findLargestSubmatrixWithSumK(mat, k);
cout << "Largest sub-matrix with sum " << k << ":\n" ;
for (vector< int >& row : largestSubmatrix) {
for ( int val : row) {
cout << val << " " ;
}
cout << endl;
}
return 0;
}
|
Java
import java.util.ArrayList;
public class Main {
public static ArrayList<ArrayList<Integer>> findLargestSubmatrixWithSumK( int [][] mat, int k) {
int m = mat.length;
int n = mat[ 0 ].length;
ArrayList<ArrayList<Integer>> maxSubmatrix = new ArrayList<>();
int maxSize = 0 ;
for ( int r = 0 ; r < m; r++) {
for ( int c = 0 ; c < n; c++) {
for ( int rEnd = r; rEnd < m; rEnd++) {
for ( int cEnd = c; cEnd < n; cEnd++) {
int submatrixSum = 0 ;
for ( int i = r; i <= rEnd; i++) {
for ( int j = c; j <= cEnd; j++) {
submatrixSum += mat[i][j];
}
}
if (submatrixSum == k && (rEnd - r + 1 ) * (cEnd - c + 1 ) > maxSize) {
maxSubmatrix.clear();
for ( int i = r; i <= rEnd; i++) {
ArrayList<Integer> row = new ArrayList<>();
for ( int j = c; j <= cEnd; j++) {
row.add(mat[i][j]);
}
maxSubmatrix.add(row);
}
maxSize = (rEnd - r + 1 ) * (cEnd - c + 1 );
}
}
}
}
}
return maxSubmatrix;
}
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 k = 7 ;
ArrayList<ArrayList<Integer>> largestSubmatrix = findLargestSubmatrixWithSumK(mat, k);
System.out.println( "Largest sub-matrix with sum " + k + ":" );
for (ArrayList<Integer> row : largestSubmatrix) {
for ( int val : row) {
System.out.print(val + " " );
}
System.out.println();
}
}
}
|
Python
def findLargestSubmatrixWithSumK(mat, k):
m = len (mat)
n = len (mat[ 0 ])
maxSubmatrix = []
maxSize = 0
for r in range (m):
for c in range (n):
for rEnd in range (r, m):
for cEnd in range (c, n):
submatrixSum = 0
for i in range (r, rEnd + 1 ):
for j in range (c, cEnd + 1 ):
submatrixSum + = mat[i][j]
if submatrixSum = = k and (rEnd - r + 1 ) * (cEnd - c + 1 ) > maxSize:
maxSubmatrix = []
for i in range (r, rEnd + 1 ):
row = mat[i][c:cEnd + 1 ]
maxSubmatrix.append(row)
maxSize = (rEnd - r + 1 ) * (cEnd - c + 1 )
return maxSubmatrix
mat = [[ 1 , 2 , 3 ],
[ 4 , 5 , 6 ],
[ 7 , 8 , 9 ]]
k = 12
largestSubmatrix = findLargestSubmatrixWithSumK(mat, k)
print ( "Largest sub-matrix with sum" , k, ":" )
for row in largestSubmatrix:
print (row)
|
C#
using System;
using System.Collections.Generic;
public class Program {
public static List<List< int > >
FindLargestSubmatrixWithSumK( int [, ] mat, int k)
{
int m = mat.GetLength(
0);
int n = mat.GetLength(
1);
List<List< int > > maxSubmatrix
= new List<List< int > >();
int maxSize = 0;
for ( int r = 0; r < m; r++) {
for ( int c = 0; c < n; c++) {
for ( int rEnd = r; rEnd < m; rEnd++) {
for ( int cEnd = c; cEnd < n; cEnd++) {
int submatrixSum
= 0;
for ( int i = r; i <= rEnd; i++) {
for ( int j = c; j <= cEnd;
j++) {
submatrixSum += mat[i, j];
}
}
if (submatrixSum == k
&& (rEnd - r + 1)
* (cEnd - c + 1)
> maxSize) {
maxSubmatrix
.Clear();
for ( int i = r; i <= rEnd;
i++) {
List< int > row
= new List< int >();
for ( int j = c; j <= cEnd;
j++) {
row.Add(mat[i, j]);
}
maxSubmatrix.Add(
row);
}
maxSize
= (rEnd - r + 1)
* (cEnd - c
+ 1);
}
}
}
}
}
return maxSubmatrix;
}
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 k = 7;
List<List< int > > largestSubmatrix
= FindLargestSubmatrixWithSumK(mat, k);
Console.WriteLine( "Largest sub-matrix with sum " + k
+ ":" );
foreach (List< int > row in largestSubmatrix)
{
foreach ( int val in row)
{
Console.Write(val + " " );
}
Console.WriteLine();
}
}
}
|
Javascript
"use strict" ;
function findLargestSubmatrixWithSumK(mat, k) {
let m = mat.length;
let n = mat[0].length;
let maxSubmatrix = [];
let maxSize = 0;
for (let r = 0; r < m; r++) {
for (let c = 0; c < n; c++) {
for (let rEnd = r; rEnd < m; rEnd++) {
for (let cEnd = c; cEnd < n; cEnd++) {
let submatrixSum = 0;
for (let i = r; i <= rEnd; i++) {
for (let j = c; j <= cEnd; j++) {
submatrixSum += mat[i][j];
}
}
if (submatrixSum === k && (rEnd - r + 1) * (cEnd - c + 1) > maxSize) {
maxSubmatrix = [];
for (let i = r; i <= rEnd; i++) {
let row = mat[i].slice(c, cEnd + 1);
maxSubmatrix.push(row);
}
maxSize = (rEnd - r + 1) * (cEnd - c + 1);
}
}
}
}
}
return maxSubmatrix;
}
let mat = [[ 1, 7, -6, 5 ],
[ -8, 6, 7, -2 ],
[ 10, -15, 3, 2 ],
[ -5, 2, 0, 9 ]];
let k = 7;
let largestSubmatrix = findLargestSubmatrixWithSumK(mat, k);
console.log( "Largest sub-matrix with sum " + k + ":" );
for (let row of largestSubmatrix) {
console.log(row.join( " " ));
}
|
Output
Largest sub-matrix with sum 7:
7 -6 5
6 7 -2
-15 3 2
Complexity Analysis
Time Complexity: O(n^4) . Auxiliary Space:O(n^2). .
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.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
const int MAX = 100;
bool sumEqualToK( int arr[], int & start,
int & end, int n, int k)
{
unordered_map< int , int > um;
int sum = 0, maxLen = 0;
for ( int i = 0; i < n; i++) {
sum += arr[i];
if (sum == k) {
maxLen = i + 1;
start = 0;
end = i;
}
if (um.find(sum) == um.end())
um[sum] = i;
if (um.find(sum - k) != um.end()) {
if (maxLen < (i - um[sum - k])) {
maxLen = i - um[sum - k];
start = um[sum - k] + 1;
end = i;
}
}
}
return (maxLen != 0);
}
void sumZeroMatrix( int mat[][MAX], int row, int col, int k)
{
int temp[row], area;
bool sum;
int up, down;
int fup = 0, fdown = 0, fleft = 0, fright = 0;
int maxArea = INT_MIN;
for ( int left = 0; left < col; left++) {
memset (temp, 0, sizeof (temp));
for ( int right = left; right < col; right++) {
for ( int i = 0; i < row; i++)
temp[i] += mat[i][right];
sum = sumEqualToK(temp, up, down, row, k);
area = (down - up + 1) * (right - left + 1);
if (sum && maxArea < area) {
fup = up;
fdown = down;
fleft = left;
fright = right;
maxArea = area;
}
}
}
if (fup == 0 && fdown == 0 && fleft == 0 &&
fright == 0 && mat[0][0] != k) {
cout << "No sub-matrix with sum " << k << " exists" ;
return ;
}
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;
}
}
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
import java.util.*;
class GFG
{
static int MAX = 100 ;
static int start, end;
static boolean sumEqualToK( int arr[], int n, int k)
{
HashMap<Integer,Integer> um =
new HashMap<Integer,Integer>();
int sum = 0 , maxLen = 0 ;
for ( int i = 0 ; i < n; i++)
{
sum += arr[i];
if (sum == k)
{
maxLen = i + 1 ;
start = 0 ;
end = i;
}
if (!um.containsKey(sum))
um.put(sum, i);
if (um.containsKey(sum - k))
{
if (maxLen < (i - um.get(sum - k)))
{
maxLen = i - um.get(sum - k);
start = um.get(sum - k) + 1 ;
end = i;
}
}
}
return (maxLen != 0 );
}
static void sumZeroMatrix( int mat[][], int row,
int col, int k)
{
int []temp = new int [row];
int area;
boolean sum = false ;
int fup = 0 , fdown = 0 , fleft = 0 , fright = 0 ;
int maxArea = Integer.MIN_VALUE;
for ( int left = 0 ; left < col; left++)
{
temp = memset(temp, 0 );
for ( int right = left; right < col; right++)
{
for ( int i = 0 ; i < row; i++)
temp[i] += mat[i][right];
sum = sumEqualToK(temp, row, k);
area = (end - start + 1 ) * (right - left + 1 );
if (sum && maxArea < area)
{
fup = start;
fdown = end;
fleft = left;
fright = right;
maxArea = area;
}
}
}
if (fup == 0 && fdown == 0 && fleft == 0 &&
fright == 0 && mat[ 0 ][ 0 ] != k)
{
System.out.print( "No sub-matrix with sum "
+ k + " exists" );
return ;
}
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;
}
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);
}
}
|
Python3
import sys
class GFG :
MAX = 100
start = 0
end = 0
@staticmethod
def sumEqualToK( arr, n, k) :
um = dict ()
sum = 0
maxLen = 0
i = 0
while (i < n) :
sum + = arr[i]
if ( sum = = k) :
maxLen = i + 1
GFG.start = 0
GFG.end = i
if ( not ( sum in um.keys())) :
um[ sum ] = i
if (( sum - k in um.keys())) :
if (maxLen < (i - um.get( sum - k))) :
maxLen = i - um.get( sum - k)
GFG.start = um.get( sum - k) + 1
GFG.end = i
i + = 1
return (maxLen ! = 0 )
@staticmethod
def sumZeroMatrix( mat, row, col, k) :
temp = [ 0 ] * (row)
area = 0
sum = False
fup = 0
fdown = 0
fleft = 0
fright = 0
maxArea = - sys.maxsize
left = 0
while (left < col) :
temp = GFG.memset(temp, 0 )
right = left
while (right < col) :
i = 0
while (i < row) :
temp[i] + = mat[i][right]
i + = 1
sum = GFG.sumEqualToK(temp, row, k)
area = (GFG.end - GFG.start + 1 ) * (right - left + 1 )
if ( sum and maxArea < area) :
fup = GFG.start
fdown = GFG.end
fleft = left
fright = right
maxArea = area
right + = 1
left + = 1
if (fup = = 0 and fdown = = 0 and fleft = = 0 and fright = = 0 and mat[ 0 ][ 0 ] ! = k) :
print ( "No sub-matrix with sum " + str (k) + " exists" , end = "")
return
print ( "(Top, Left): " + "(" + str (fup) + ", " + str (fleft) + ")" + "\n" , end = "")
print ( "(Bottom, Right): " + "(" + str (fdown) + ", " + str (fright) + ")" + "\n" , end = "")
j = fup
while (j < = fdown) :
i = fleft
while (i < = fright) :
print ( str (mat[j][i]) + " " , end = "")
i + = 1
print ()
j + = 1
@staticmethod
def memset( arr, val) :
i = 0
while (i < len (arr)) :
arr[i] = val
i + = 1
return arr
@staticmethod
def main( args) :
mat = [[ 1 , 7 , - 6 , 5 ], [ - 8 , 6 , 7 , - 2 ], [ 10 , - 15 , 3 , 2 ], [ - 5 , 2 , 0 , 9 ]]
row = 4
col = 4
k = 7
GFG.sumZeroMatrix(mat, row, col, k)
if __name__ = = "__main__" :
GFG.main([])
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static int MAX = 100;
static int start, end;
static bool sumEqualToK( int []arr, int n, int k)
{
Dictionary< int , int > um =
new Dictionary< int , int >();
int sum = 0, maxLen = 0;
for ( int i = 0; i < n; i++)
{
sum += arr[i];
if (sum == k)
{
maxLen = i + 1;
start = 0;
end = i;
}
if (!um.ContainsKey(sum))
um.Add(sum, i);
if (um.ContainsKey(sum - k))
{
if (maxLen < (i - um[sum - k]))
{
maxLen = i - um[sum - k];
start = um[sum - k] + 1;
end = i;
}
}
}
return (maxLen != 0);
}
static void sumZeroMatrix( int [,]mat, int row,
int col, int k)
{
int []temp = new int [row];
int area;
bool sum = false ;
int fup = 0, fdown = 0, fleft = 0, fright = 0;
int maxArea = int .MinValue;
for ( int left = 0; left < col; left++)
{
temp = memset(temp, 0);
for ( int right = left; right < col; right++)
{
for ( int i = 0; i < row; i++)
temp[i] += mat[i, right];
sum = sumEqualToK(temp, row, k);
area = (end - start + 1) * (right - left + 1);
if (sum && maxArea < area)
{
fup = start;
fdown = end;
fleft = left;
fright = right;
maxArea = area;
}
}
}
if (fup == 0 && fdown == 0 && fleft == 0 &&
fright == 0 && mat[0, 0] != k)
{
Console.Write( "No sub-matrix with sum "
+ k + " exists" );
return ;
}
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;
}
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);
}
}
|
Javascript
var MAX = 100;
var start;
var end;
function sumEqualToK(arr, n, k){
var um = new Map();
var sum = 0, maxLen = 0;
for (let i=0;i<n;i++){
sum += arr[i];
if (sum==k){
maxLen = i+1;
start = 0;
end = i;
}
if (!um.has(sum)){
um.set(sum, i);
}
if (um.has(sum-k)){
if (maxLen < (i - um.get(sum - k))){
maxLen = i-um.get(sum-k);
start = um.get(sum-k) + 1;
end = i;
}
}
}
return (maxLen!=0);
}
function sumZeroMatrix(mat, row, col, k){
var temp = new Array(row);
var area;
var sum = false ;
var fup = 0, fdown = 0, fleft = 0, fright = 0;
var maxArea = Number.MIN_VALUE;
for (let left = 0; left < col; left++)
{
temp = memset(temp, 0);
for (let right = left; right < col; right++)
{
for (let i = 0; i < row; i++){
temp[i] += mat[i][right];
}
sum = sumEqualToK(temp, row, k);
area = (end - start + 1) * (right - left + 1);
if (sum && maxArea < area)
{
fup = start;
fdown = end;
fleft = left;
fright = right;
maxArea = area;
}
}
}
if (fup == 0 && fdown == 0 && fleft == 0 &&
fright == 0 && mat[0][0] != k)
{
console.log( "No sub-matrix with sum "
+ k + " exists" );
return ;
}
console.log( "(Top, Left): "
+ "(" + fup+ ", " + fleft
+ ")" + "<br>" );
console.log( "(Bottom, Right): "
+ "(" + fdown+ ", " + fright
+ ")" + "<br>" );
for (let j = fup; j <= fdown; j++)
{
for (let i = fleft; i <= fright; i++)
{
console.log(mat[j][i] + " " );
}
console.log( "<br>" );
}
}
function memset(arr, val){
for (let i = 0; i < arr.length; i++){
arr[i] = val;
}
return arr;
}
var mat = [[1, 7, -6, 5],
[-8, 6, 7, -2],
[10, -15, 3, 2],
[-5, 2, 0, 9]];
var row = 4, col = 4;
var k = 7;
sumZeroMatrix(mat, row, col, k);
|
Output
(Top, Left): (0, 1)
(Bottom, Right): (2, 3)
7 -6 5
6 7 -2
-15 3 2
Complexity Analysis
- Time Complexity: O(n^3).
- Auxiliary Space: O(n).
|