Given a matrix mat[][] of size n à m and a query matrix queries[][] of size q à 2, where each query queries[i] = [a, b] represents the dimensions of a submatrix, find the maximum sum among all contiguous a à b submatrices for each query.
Output: [9, 20, 38] Explanation: For 1 Ã 1, the maximum submatrix sum is 9. For 2 Ã 2, the possible submatrix sums are 12, 16, 20, 20, 16, 16. The maximum is 20. For 3 Ã 3, the possible submatrix sums are 34 and 38. The maximum is 38. Therefore, the answer is [9, 20, 38].
Input: mat[][] = [[1, 2, 3, 9], [4, 5, 6, 2], [8, 3, 2, 6]], queries[][] = [[3,2]] Output: [28] Explanation: For a = 3 and b = 2, the possible 3 Ã 2 submatrices have sums 23, 21, and 28. The maximum is 28.
[Naive Approach] Check Every Possible Submatrix for Every Query - O(q à n à m à a à b) Time and O(1) Space
The idea is to process each query independently. For a query (a, b), generate every possible contiguous a à b submatrix in the matrix and calculate its sum by traversing all its elements. Among all possible submatrices, keep track of the maximum sum and store it as the answer for that query.
C++
#include<bits/stdc++.h>usingnamespacestd;vector<int>maxSubMatSum(vector<vector<int>>&mat,vector<vector<int>>&queries){intn=mat.size();intm=mat[0].size();vector<int>res;// Process each query independentlyfor(auto&qr:queries){inta=qr[0];intb=qr[1];intmx=INT_MIN;// Try every possible a x b submatrixfor(introw=0;row+a<=n;row++){for(intcol=0;col+b<=m;col++){intcurrSum=0;// Calculate current submatrix sumfor(inti=row;i<row+a;i++){for(intj=col;j<col+b;j++){currSum+=mat[i][j];}}mx=max(mx,currSum);}}res.push_back(mx);}returnres;}intmain(){intn=3,m=4;vector<vector<int>>mat={{1,2,3,9},{4,5,6,2},{8,3,2,6}};intq=3;vector<vector<int>>queries={{1,1},{2,2},{3,3}};vector<int>ans=maxSubMatSum(mat,queries);cout<<"[";for(inti=0;i<ans.size();i++){cout<<ans[i];if(i!=ans.size()-1){cout<<", ";}}cout<<"]";return0;}
Java
importjava.util.ArrayList;classGFG{publicstaticArrayList<Integer>maxSubMatSum(int[][]mat,int[][]queries){intn=mat.length;intm=mat[0].length;ArrayList<Integer>res=newArrayList<>();// Process each query independentlyfor(int[]qr:queries){inta=qr[0];intb=qr[1];intmx=Integer.MIN_VALUE;// Try every possible a x b submatrixfor(introw=0;row+a<=n;row++){for(intcol=0;col+b<=m;col++){intcurrSum=0;// Calculate current submatrix sumfor(inti=row;i<row+a;i++){for(intj=col;j<col+b;j++){currSum+=mat[i][j];}}mx=Math.max(mx,currSum);}}res.add(mx);}returnres;}publicstaticvoidmain(String[]args){intn=3,m=4;int[][]mat={{1,2,3,9},{4,5,6,2},{8,3,2,6}};intq=3;int[][]queries={{1,1},{2,2},{3,3}};ArrayList<Integer>ans=maxSubMatSum(mat,queries);System.out.print(ans);}}
Python
defmaxSubMatSum(mat,queries):n=len(mat)m=len(mat[0])res=[]# Process each query independentlyforqrinqueries:a=qr[0]b=qr[1]mx=float('-inf')# Try every possible a x b submatrixforrowinrange(n-a+1):forcolinrange(m-b+1):currSum=0# Calculate current submatrix sumforiinrange(row,row+a):forjinrange(col,col+b):currSum+=mat[i][j]mx=max(mx,currSum)res.append(mx)returnresif__name__=='__main__':mat=[[1,2,3,9],[4,5,6,2],[8,3,2,6]]queries=[[1,1],[2,2],[3,3]]ans=maxSubMatSum(mat,queries)print('[',end='')foriinrange(len(ans)):print(ans[i],end=''ifi==len(ans)-1else', ')print(']')
C#
usingSystem;usingSystem.Collections.Generic;classGFG{publicList<int>maxSubMatSum(int[,]mat,int[,]queries){intn=mat.GetLength(0);intm=mat.GetLength(1);intq=queries.GetLength(0);List<int>res=newList<int>();// Process each query independentlyfor(intk=0;k<q;k++){inta=queries[k,0];intb=queries[k,1];intmx=int.MinValue;// Try every possible a x b submatrixfor(introw=0;row+a<=n;row++){for(intcol=0;col+b<=m;col++){intcurrSum=0;// Calculate current submatrix sumfor(inti=row;i<row+a;i++){for(intj=col;j<col+b;j++){currSum+=mat[i,j];}}mx=Math.Max(mx,currSum);}}res.Add(mx);}returnres;}staticvoidMain(string[]args){int[,]mat={{1,2,3,9},{4,5,6,2},{8,3,2,6}};int[,]queries={{1,1},{2,2},{3,3}};GFGgfg=newGFG();List<int>ans=gfg.maxSubMatSum(mat,queries);Console.Write("[");for(inti=0;i<ans.Count;i++){Console.Write(ans[i]);if(i!=ans.Count-1){Console.Write(", ");}}Console.WriteLine("]");}}
JavaScript
functionmaxSubMatSum(mat,queries){constn=mat.length;constm=mat[0].length;constres=[];// Process each query independentlyfor(constqrofqueries){consta=qr[0];constb=qr[1];letmx=Number.NEGATIVE_INFINITY;// Try every possible a x b submatrixfor(letrow=0;row+a<=n;row++){for(letcol=0;col+b<=m;col++){letcurrSum=0;// Calculate current submatrix sumfor(leti=row;i<row+a;i++){for(letj=col;j<col+b;j++){currSum+=mat[i][j];}}mx=Math.max(mx,currSum);}}res.push(mx);}returnres;}(function(){constmat=[[1,2,3,9],[4,5,6,2],[8,3,2,6]];constqueries=[[1,1],[2,2],[3,3]];constans=maxSubMatSum(mat,queries);console.log("[");for(leti=0;i<ans.length;i++){console.log(ans[i]);if(i!==ans.length-1){console.log(", ");}}console.log("]");})();
Output
[9, 20, 38]
[Expected Approach] Using 2D Prefix Sum - O(q * n * m) Time and O(n * m) Space
The idea is to first build a 2D prefix sum array that stores the cumulative sum of elements in the matrix. Using this prefix sum array, the sum of any a à b submatrix can be obtained directly. Then, for each query, traverse all possible a à b submatrices, find their sums using the prefix sum array, and maintain the maximum sum obtained.
Let us understand with example: Input: n = 3, m = 4, mat[][] = [[1, 2, 3, 9], [4, 5, 6, 2], [8, 3, 2, 6]], q = 3, queries[][] = [[1, 1], [2, 2], [3, 3]]
For query (1, 1), every cell itself forms a submatrix. The maximum value in the matrix is 9.
For query (2, 2), the possible submatrix sums are 12, 16, 20, 20, 16, 16. Hence, the maximum sum is 20.
For query (3, 3), the two possible submatrix sums are 34 and 38. Hence, the maximum sum is 38.
Therefore, the final answer is [9, 20, 38].
C++
#include<bits/stdc++.h>usingnamespacestd;// Returns the sum of submatrix [(r1, c1) ... (r2, c2)]// using the 2D prefix sum array.intgetSum(vector<vector<int>>&pre,intr1,intc1,intr2,intc2){returnpre[r2+1][c2+1]-pre[r1][c2+1]-pre[r2+1][c1]+pre[r1][c1];}vector<int>maxSubMatSum(vector<vector<int>>&mat,vector<vector<int>>&queries){intn=mat.size();intm=mat[0].size();intq=queries.size();// Build 2D prefix sum array.vector<vector<int>>pre(n+1,vector<int>(m+1,0));for(inti=1;i<=n;i++){for(intj=1;j<=m;j++){pre[i][j]=mat[i-1][j-1]+pre[i-1][j]+pre[i][j-1]-pre[i-1][j-1];}}vector<int>res;res.reserve(q);// Process each query independently.for(auto&qr:queries){inta=qr[0];intb=qr[1];intmx=INT_MIN;// Try every possible a x b submatrix.for(inti=0;i+a<=n;i++){for(intj=0;j+b<=m;j++){intsum=getSum(pre,i,j,i+a-1,j+b-1);mx=max(mx,sum);}}res.push_back(mx);}returnres;}intmain(){intn=3,m=4;vector<vector<int>>mat={{1,2,3,9},{4,5,6,2},{8,3,2,6}};intq=3;vector<vector<int>>queries={{1,1},{2,2},{3,3}};vector<int>ans=maxSubMatSum(mat,queries);cout<<"[";for(inti=0;i<ans.size();i++){cout<<ans[i];if(i!=ans.size()-1){cout<<", ";}}cout<<"]";return0;}
Java
importjava.util.ArrayList;importjava.util.List;classGFG{// Returns the sum of submatrix [(r1, c1) ... (r2, c2)]// using the 2D prefix sum array.publicstaticintgetSum(int[][]pre,intr1,intc1,intr2,intc2){returnpre[r2+1][c2+1]-pre[r1][c2+1]-pre[r2+1][c1]+pre[r1][c1];}publicstaticList<Integer>maxSubMatSum(int[][]mat,int[][]queries){intn=mat.length;intm=mat[0].length;intq=queries.length;// Build 2D prefix sum array.int[][]pre=newint[n+1][m+1];for(inti=1;i<=n;i++){for(intj=1;j<=m;j++){pre[i][j]=mat[i-1][j-1]+pre[i-1][j]+pre[i][j-1]-pre[i-1][j-1];}}List<Integer>res=newArrayList<>(q);// Process each query independently.for(int[]qr:queries){inta=qr[0];intb=qr[1];intmx=Integer.MIN_VALUE;// Try every possible a x b submatrix.for(inti=0;i+a<=n;i++){for(intj=0;j+b<=m;j++){intsum=getSum(pre,i,j,i+a-1,j+b-1);mx=Math.max(mx,sum);}}res.add(mx);}returnres;}publicstaticvoidmain(String[]args){intn=3,m=4;int[][]mat={{1,2,3,9},{4,5,6,2},{8,3,2,6}};intq=3;int[][]queries={{1,1},{2,2},{3,3}};List<Integer>ans=maxSubMatSum(mat,queries);System.out.print("[");for(inti=0;i<ans.size();i++){System.out.print(ans.get(i));if(i!=ans.size()-1){System.out.print(", ");}}System.out.print("]");}}
Python
# Returns the sum of submatrix [(r1, c1) ... (r2, c2)]# using the 2D prefix sum array.defgetSum(pre,r1,c1,r2,c2):return(pre[r2+1][c2+1]-pre[r1][c2+1]-pre[r2+1][c1]+pre[r1][c1])defmaxSubMatSum(mat,queries):n=len(mat)m=len(mat[0])q=len(queries)# Build 2D prefix sum array.pre=[[0]*(m+1)for_inrange(n+1)]foriinrange(1,n+1):forjinrange(1,m+1):pre[i][j]=(mat[i-1][j-1]+pre[i-1][j]+pre[i][j-1]-pre[i-1][j-1])res=[]# Process each query independently.forqrinqueries:a,b=qrmx=float('-inf')# Try every possible a x b submatrix.foriinrange(n-a+1):forjinrange(m-b+1):sumVal=getSum(pre,i,j,i+a-1,j+b-1)mx=max(mx,sumVal)res.append(mx)returnresif__name__=="__main__":n,m=3,4mat=[[1,2,3,9],[4,5,6,2],[8,3,2,6]]q=3queries=[[1,1],[2,2],[3,3]]ans=maxSubMatSum(mat,queries)print(ans)
C#
usingSystem;usingSystem.Collections.Generic;classGFG{// Returns the sum of submatrix [(r1, c1) ... (r2, c2)]// using the 2D prefix sum array.staticintgetSum(int[,]pre,intr1,intc1,intr2,intc2){returnpre[r2+1,c2+1]-pre[r1,c2+1]-pre[r2+1,c1]+pre[r1,c1];}staticList<int>maxSubMatSum(int[,]mat,int[,]queries){intn=mat.GetLength(0);intm=mat.GetLength(1);intq=queries.GetLength(0);// Build 2D prefix sum array.int[,]pre=newint[n+1,m+1];for(inti=1;i<=n;i++){for(intj=1;j<=m;j++){pre[i,j]=mat[i-1,j-1]+pre[i-1,j]+pre[i,j-1]-pre[i-1,j-1];}}List<int>res=newList<int>();// Process each query independently.for(intk=0;k<q;k++){inta=queries[k,0];intb=queries[k,1];intmx=int.MinValue;// Try every possible a x b submatrix.for(inti=0;i+a<=n;i++){for(intj=0;j+b<=m;j++){intsum=getSum(pre,i,j,i+a-1,j+b-1);mx=Math.Max(mx,sum);}}res.Add(mx);}returnres;}publicstaticvoidMain(){int[,]mat={{1,2,3,9},{4,5,6,2},{8,3,2,6}};int[,]queries={{1,1},{2,2},{3,3}};List<int>ans=maxSubMatSum(mat,queries);Console.Write("[");for(inti=0;i<ans.Count;i++){Console.Write(ans[i]);if(i!=ans.Count-1){Console.Write(", ");}}Console.WriteLine("]");}}
JavaScript
functiongetSum(pre,r1,c1,r2,c2){returnpre[r2+1][c2+1]-pre[r1][c2+1]-pre[r2+1][c1]+pre[r1][c1];}functionmaxSubMatSum(mat,queries){letn=mat.length;letm=mat[0].length;letq=queries.length;// Build 2D prefix sum array.letpre=Array.from({length:n+1},()=>Array(m+1).fill(0));for(leti=1;i<=n;i++){for(letj=1;j<=m;j++){pre[i][j]=mat[i-1][j-1]+pre[i-1][j]+pre[i][j-1]-pre[i-1][j-1];}}letres=[];// Process each query independently.for(letqrofqueries){leta=qr[0];letb=qr[1];letmx=-Infinity;// Try every possible a x b submatrix.for(leti=0;i+a<=n;i++){for(letj=0;j+b<=m;j++){letsum=getSum(pre,i,j,i+a-1,j+b-1);mx=Math.max(mx,sum);}}res.push(mx);}returnres;}functionmain(){letn=3,m=4;letmat=[[1,2,3,9],[4,5,6,2],[8,3,2,6]];letq=3;letqueries=[[1,1],[2,2],[3,3]];letans=maxSubMatSum(mat,queries);console.log('[');for(leti=0;i<ans.length;i++){console.log(ans[i]);if(i!=ans.length-1){console.log(', ');}}console.log(']');}main();