Maximum sum not exceeding K possible for any rectangle of a Matrix
Last Updated :
02 Sep, 2022
Given a matrix mat[][] of dimensions N * M, and an integer K, the task is to find the maximum sum of any rectangle possible from the given matrix, whose sum of elements is at most K.
Examples:
Input: mat[][] ={{1, 0, 1}, {0, -2, 3}}, K = 2
Output: 2
Explanation: The maximum sum possible in any rectangle from the matrix is 2 (<= K), obtained from the matrix {{0, 1}, {-2, 3}}.
Input: mat[][] = {{2, 2, -1}}, K = 3
Output: 3
Explanation: The maximum sum rectangle is {{2, 2, -1}} is 3 ( <- K).
Naive Approach: The simplest approach is to check for all possible submatrices from the given matrix whether the sum of its elements is at most K or not. If found to be true, store the sum of that submatrix. Finally, print the maximum sum of such submatrices obtained.
Time Complexity: O(N6)
Auxiliary Space: O(1)
Efficient Approach: The above approach can be optimized by using an approach similar to finding the maximum sum rectangle in a 2D matrix. The only difference is that the sum of the rectangle must not exceed K. The idea is to fix the left and right columns one by one and in each iteration, store the sum of each row in the current rectangle and find the maximum subarray sum less than K in this array. Follow the steps below to solve the problem:
- Initialize a variable, say res, that stores the maximum sum of elements of the submatrix having sum at most K.
- Iterate over the range [0, M – 1] using the variable i for the left column and perform the following steps:
- Initialize an array V[] of size N, to store the sum of elements of each row in between the left and right column pair.
- Iterate over the range [0, M – 1] using a variable j for the right column and perform the following steps:
- Find the sum between current left and right column of every row and update the sum in the array V[].
- Find the maximum sum subarray with sum less than K in V[] and store the result in ans.
- If the value of ans is greater than the value of res, update res to ans.
- After completing the above steps, print the value of res as the result.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int maxSubarraySum(vector< int >& sum,
int k, int row)
{
int curSum = 0, curMax = INT_MIN;
set< int > sumSet;
sumSet.insert(0);
for ( int r = 0; r < row; ++r) {
curSum += sum[r];
auto it = sumSet.lower_bound(curSum - k);
if (it != sumSet.end()) {
curMax = max(curMax,
curSum - *it);
}
sumSet.insert(curSum);
}
return curMax;
}
void maxSumSubmatrix(
vector<vector< int > >& matrix, int k)
{
int row = matrix.size();
int col = matrix[0].size();
int ret = INT_MIN;
for ( int i = 0; i < col; ++i) {
vector< int > sum(row, 0);
for ( int j = i; j < col; ++j) {
for ( int r = 0; r < row; ++r) {
sum[r] += matrix[r][j];
}
int curMax = maxSubarraySum(
sum, k, row);
ret = max(ret, curMax);
}
}
cout << ret;
}
int main()
{
vector<vector< int > > matrix
= { { 1, 0, 1 }, { 0, -2, 3 } };
int K = 2;
maxSumSubmatrix(matrix, K);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
static int maxSubarraySum( int [] sum, int k, int row)
{
int curSum = 0 , curMax = Integer.MIN_VALUE;
TreeSet<Integer> sumSet = new TreeSet<Integer>();
sumSet.add( 0 );
for ( int r = 0 ; r < row; ++r) {
curSum += sum[r];
Integer target = sumSet.ceiling(curSum - k);
if (target != null ) {
curMax = Math.max(curMax, curSum - target);
}
sumSet.add(curSum);
}
return curMax;
}
static void maxSumSubmatrix( int [][] matrix, int k)
{
int row = matrix.length;
int col = matrix[ 0 ].length;
int ret = Integer.MIN_VALUE;
for ( int i = 0 ; i < col; ++i) {
int [] sum = new int [row];
for ( int j = i; j < col; ++j) {
for ( int r = 0 ; r < row; ++r) {
sum[r] += matrix[r][j];
}
int curMax = maxSubarraySum(sum, k, row);
ret = Math.max(ret, curMax);
}
}
System.out.print(ret);
}
public static void main(String[] args)
{
int [][] matrix = { { 5 , - 4 , - 3 , 4 },
{ - 3 , - 4 , 4 , 5 },
{ 5 , 1 , 5 , - 4 } };
int K = 8 ;
maxSumSubmatrix(matrix, K);
}
}
|
Python3
from bisect import bisect_left, bisect_right
import sys
def maxSubarraySum( sum , k, row):
curSum, curMax = 0 , - sys.maxsize - 1
sumSet = {}
sumSet[ 0 ] = 1
for r in range (row):
curSum + = sum [r]
arr = list (sumSet.keys())
it = bisect_left(arr, curSum - k)
if (it ! = len (arr)):
curMax = max (curMax, curSum - it)
sumSet[curSum] = 1
return curMax
def maxSumSubmatrix(matrix, k):
row = len (matrix)
col = len (matrix[ 0 ])
ret = - sys.maxsize - 1
for i in range (col):
sum = [ 0 ] * (row)
for j in range (i, col):
for r in range (row):
sum [r] + = matrix[r][j]
curMax = maxSubarraySum( sum , k, row)
ret = max (ret, curMax)
print (ret)
if __name__ = = '__main__' :
matrix = [ [ 1 , 0 , 1 ], [ 0 , - 2 , 3 ] ]
K = 2
maxSumSubmatrix(matrix, K)
|
C#
using System;
using System.Collections.Generic;
class GFG{
static int maxSubarraySum( int [] sum, int k, int row)
{
int curSum = 0, curMax = Int32.MinValue;
HashSet< int > sumSet = new HashSet< int >();
sumSet.Add(0);
for ( int r = 0; r < row; ++r)
{
curSum += sum[r];
List< int > list = new List< int >();
list.AddRange(sumSet);
int it = list.LastIndexOf(curSum - k);
if (it > -1)
{
curMax = Math.Max(curMax,
curSum - it);
}
sumSet.Add(curSum);
}
return curMax;
}
static void maxSumSubmatrix( int [,] matrix, int k)
{
int row = matrix.GetLength(0);
int col = matrix.GetLength(1);
int ret = Int32.MinValue;
for ( int i = 0; i < col; ++i)
{
int [] sum = new int [row];
for ( int j = i; j < col; ++j)
{
for ( int r = 0; r < row; ++r)
{
sum[r] += matrix[r, j];
}
int curMax = maxSubarraySum(
sum, k, row);
ret = Math.Max(ret, curMax);
}
}
Console.Write(ret);
}
static public void Main()
{
int [,] matrix = { { 1, 0, 1 },
{ 0, -2, 3 } };
int K = 2;
maxSumSubmatrix(matrix, K);
}
}
|
Javascript
<script>
function maxSubarraySum(sum,k,row)
{
let curSum = 0, curMax = Number.MIN_VALUE;
let sumSet = new Set();
sumSet.add(0);
for (let r = 0; r < row; ++r)
{
curSum += sum[r];
let list = [];
list=Array.from(sumSet);
let it = list.lastIndexOf(curSum - k);
if (it >-1)
{
curMax = Math.max(curMax,
curSum - it);
}
sumSet.add(curSum);
}
return curMax;
}
function maxSumSubmatrix(matrix, k)
{
let row = matrix.length;
let col = matrix[0].length;
let ret = Number.MIN_VALUE;
for (let i = 0; i < col; ++i)
{
let sum = new Array(row);
for (let j=0;j<row;j++)
sum[j]=0;
for (let j = i; j < col; ++j)
{
for (let r = 0; r < row; ++r)
{
sum[r] += matrix[r][j];
}
let curMax = maxSubarraySum(
sum, k, row);
ret = Math.max(ret, curMax);
}
}
document.write(ret);
}
let matrix=[[ 1, 0, 1 ],
[ 0, -2, 3 ]];
let K = 2;
maxSumSubmatrix(matrix, K)
</script>
|
Time Complexity: O(N3*log(N))
Auxiliary Space: O(N)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...