Maximum sum not exceeding K possible for any rectangle of a Matrix

• Difficulty Level : Hard
• Last Updated : 15 Jan, 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++

 // C++ program for the above approach #include using namespace std;   // Function to find the maximum possible // sum of  arectangle which is less than K int maxSubarraySum(vector& sum,                    int k, int row) {     int curSum = 0, curMax = INT_MIN;       // Stores the values (cum_sum - K)     set sumSet;       // Insert 0 into the set sumSet     sumSet.insert(0);       // Traverse over the rows     for (int r = 0; r < row; ++r) {           // Get cumulative sum from [0 to i]         curSum += sum[r];           // Search for upperbound of         // (cSum - K) in the hashmap         auto it = sumSet.lower_bound(curSum - k);           // If upper_bound of (cSum - K)         // exists, then update max sum         if (it != sumSet.end()) {             curMax = max(curMax,                          curSum - *it);         }           // Insert cumulative value         // in the hashmap         sumSet.insert(curSum);     }       // Return the maximum sum     // which is less than K     return curMax; }   // Function to find the maximum sum of // rectangle such that its sum is no // larger than K void maxSumSubmatrix(     vector >& matrix, int k) {     // Stores the number of rows     // and columns     int row = matrix.size();     int col = matrix.size();       // Store the required result     int ret = INT_MIN;       // Set the left column     for (int i = 0; i < col; ++i) {         vector sum(row, 0);           // Set the right column for the         // left column set by outer loop         for (int j = i; j < col; ++j) {               // Calculate sum between the             // current left and right             // for every row             for (int r = 0; r < row; ++r) {                 sum[r] += matrix[r][j];             }               // Stores the sum of rectangle             int curMax = maxSubarraySum(                 sum, k, row);               // Update the overall maximum sum             ret = max(ret, curMax);         }     }       // Print the result     cout << ret; }   // Driver Code int main() {     vector > matrix         = { { 1, 0, 1 }, { 0, -2, 3 } };     int K = 2;       // Function Call     maxSumSubmatrix(matrix, K);       return 0; }

Java

 // Java program for the above approach import java.io.*; import java.util.*;   class GFG {   // Function to find the maximum possible // sum of arectangle which is less than K     static int maxSubarraySum(int[] sum,                               int k, int row) {         int curSum = 0, curMax = Integer.MIN_VALUE;           // Stores the values (cum_sum - K)         Set sumSet = new HashSet();           // Insert 0 into the set sumSet         sumSet.add(0);           // Traverse over the rows         for (int r = 0; r < row; ++r) {               // Get cumulative sum from [0 to i]             curSum += sum[r];               // Search for upperbound of             // (cSum - K) in the hashmap             ArrayList list = new ArrayList();             list.addAll(sumSet);               int it = Integer.MIN_VALUE;             for (int e : list)                 if (e >= (curSum - k)) {                     it = e;                     break;                 }               // If upper_bound of (cSum - K)             // exists, then update max sum             if (it != Integer.MIN_VALUE) {                 curMax = Math.max(curMax,                                   curSum - it);             }               // Insert cumulative value             // in the hashmap             sumSet.add(curSum);         }           // Return the maximum sum         // which is less than K         return curMax;     }   // Function to find the maximum sum of // rectangle such that its sum is no // larger than K     static void maxSumSubmatrix(int[][] matrix, int k) {           // Stores the number of rows         // and columns         int row = matrix.length;         int col = matrix.length;           // Store the required result         int ret = Integer.MIN_VALUE;           // Set the left column         for (int i = 0; i < col; ++i) {             int[] sum = new int[row];               // Set the right column for the             // left column set by outer loop             for (int j = i; j < col; ++j) {                   // Calculate sum between the                 // current left and right                 // for every row                 for (int r = 0; r < row; ++r) {                     sum[r] += matrix[r][j];                 }                   // Stores the sum of rectangle                 int curMax = maxSubarraySum(                                  sum, k, row);                   // Update the overall maximum sum                 ret = Math.max(ret, curMax);             }         }           // Print the result         System.out.print(ret);     }   // Driver Code     public static void main (String[] args) {         int[][] matrix =  { { 5, -4, -3, 4 },             { -3, -4, 4, 5 },             {5, 1, 5, -4}         };         int K = 8;           // Function Call         maxSumSubmatrix(matrix, K);     } }   // This code is contributed by avanitrachhadiya2155

Python3

 # Python3 program for the above approach from bisect import bisect_left, bisect_right import sys   # Function to find the maximum possible # sum of  arectangle which is less than K def maxSubarraySum(sum, k, row):       curSum, curMax = 0, -sys.maxsize - 1       # Stores the values (cum_sum - K)     sumSet = {}       # Insert 0 into the set sumSet     sumSet = 1       # Traverse over the rows     for r in range(row):                   # Get cumulative sum from [0 to i]         curSum += sum[r]           # Search for upperbound of         # (cSum - K) in the hashmap         arr = list(sumSet.keys())           it = bisect_left(arr, curSum - k)           # If upper_bound of (cSum - K)         # exists, then update max sum         if (it != len(arr)):             curMax = max(curMax, curSum - it)           # Insert cumulative value         # in the hashmap         sumSet[curSum] = 1       # Return the maximum sum     # which is less than K     return curMax   # Function to find the maximum sum of # rectangle such that its sum is no # larger than K def maxSumSubmatrix(matrix, k):           # Stores the number of rows     # and columns     row = len(matrix)     col = len(matrix)       # Store the required result     ret = -sys.maxsize - 1       # Set the left column     for i in range(col):         sum =  * (row)           # Set the right column for the         # left column set by outer loop         for j in range(i, col):                           # Calculate sum between the             # current left and right             # for every row             for r in range(row):                 sum[r] += matrix[r][j]               # Stores the sum of rectangle             curMax = maxSubarraySum(sum, k, row)               # Update the overall maximum sum             ret = max(ret, curMax)       # Print the result     print(ret)   # Driver Code if __name__ == '__main__':           matrix = [ [ 1, 0, 1 ], [ 0, -2, 3 ] ]     K = 2       # Function Call     maxSumSubmatrix(matrix, K)   # This code is contributed by mohit kumar 29

C#

 // C# program for the above approach using System; using System.Collections.Generic;   class GFG{       // Function to find the maximum possible // sum of  arectangle which is less than K static int maxSubarraySum(int[] sum,int k, int row) {     int curSum = 0, curMax = Int32.MinValue;         // Stores the values (cum_sum - K)     HashSet sumSet = new HashSet();         // Insert 0 into the set sumSet     sumSet.Add(0);         // Traverse over the rows     for(int r = 0; r < row; ++r)     {                   // Get cumulative sum from [0 to i]         curSum += sum[r];             // Search for upperbound of         // (cSum - K) in the hashmap         List list = new List();         list.AddRange(sumSet);         int it = list.LastIndexOf(curSum - k);             // If upper_bound of (cSum - K)         // exists, then update max sum         if (it > -1)         {             curMax = Math.Max(curMax,                               curSum - it);         }             // Insert cumulative value         // in the hashmap         sumSet.Add(curSum);     }         // Return the maximum sum     // which is less than K     return curMax; }     // Function to find the maximum sum of // rectangle such that its sum is no // larger than K static void maxSumSubmatrix(int[,] matrix, int k) {            // Stores the number of rows     // and columns     int row = matrix.GetLength(0);     int col = matrix.GetLength(1);         // Store the required result     int ret = Int32.MinValue;         // Set the left column     for(int i = 0; i < col; ++i)     {         int[] sum = new int[row];             // Set the right column for the         // left column set by outer loop         for(int j = i; j < col; ++j)         {                            // Calculate sum between the             // current left and right             // for every row             for(int r = 0; r < row; ++r)             {                 sum[r] += matrix[r, j];             }                 // Stores the sum of rectangle             int curMax = maxSubarraySum(                 sum, k, row);                 // Update the overall maximum sum             ret = Math.Max(ret, curMax);         }     }         // Print the result     Console.Write(ret); }     // Driver Code static public void Main() {     int[,] matrix = { { 1, 0, 1 },                       { 0, -2, 3 } };     int K = 2;       // Function Call     maxSumSubmatrix(matrix, K); } }   // This code is contributed by rag2127

Javascript



Output:

2

Time Complexity: O(N3*log(N))
Auxiliary Space: O(N)

My Personal Notes arrow_drop_up
Recommended Articles
Page :