Open In App

C Program for Maximum sum rectangle in a 2D matrix | DP-27

Improve
Improve
Like Article
Like
Save
Share
Report

Write a C program for a given 2D array, the task is to find the maximum sum subarray in it. For example, in the following 2D array, the maximum sum subarray is highlighted with blue rectangle and sum of this subarray is 29.

This problem is mainly an extension of the Largest Sum Contiguous Subarray for 1D array.

C Program for Maximum sum rectangle in a 2D matrix using Naive Approach:

The Naive Solution for this problem is to check every possible rectangle in the given 2D array. This solution requires 6 nested loops –  

  • 4 for start and end coordinate of the 2 axis O(n4)
  • and 2 for the summation of the sub-matrix O(n2).

Below is the implementation of the above approach:

C




// C program for the above approach
 
#include <stdio.h>
 
void maxMatrixSum(int matrix[4][5])
 
{
    // Number of rows in the matrix
    int n = 4;
    // Number of columns in the matrix
    int m = 5;
    // Variable to store the maximum sum found so far
    int maxsum = -32768;
    // Variables to store the coordinates of the
    // subrectangle with the maximum sum
    int top = 0, bottom = 0, left = 0, right = 0;
 
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            for (int k = 0; k < n; k++) {
                for (int l = 0; l < m; l++) {
                    int curr = 0;
                    for (int x = i; x <= k; x++) {
                        for (int y = j; y <= l; y++) {
                            curr += matrix[x][y];
                        }
                    }
 
                    if (curr > maxsum) {
                        maxsum = curr;
                        top = i;
                        left = j;
                        right = l;
                        bottom = k;
                    }
                }
            }
        }
    }
 
    printf("(Top, Left) (%d, %d)\n", top, left);
    printf("(Bottom, Right) (%d, %d)\n", bottom, right);
    printf("The sum of this rectangle is: %d\n", maxsum);
}
 
// Drivers Code
int main()
{
    int v[4][5] = { { 1, 2, -1, -4, -20 },
                    { -8, -3, 4, 2, 1 },
                    { 3, 8, 10, 1, 3 },
                    { -4, -1, 1, 7, -6 } };
    maxMatrixSum(v);
    return 0;
}


Output

(Top, Left) (1, 1)
(Bottom, Right) (3, 3)
The sum of this rectangle is: 29

Time Complexity: O(n^3 * m^3) where n is the number of rows and m is the numbr of columns in the given matrix.
Auxiliary space: O(1)

C Program for Maximum sum rectangle in a 2D matrix using Kadane’s algorithm:

Approach:

  • Fix the left and right columns one by one.
  • Calculate the sum of rows between these columns and store the sums in a temporary array.
  • Apply Kadane’s 1D algorithm to the temporary array to find the maximum sum subarray.
  • Compare this maximum sum with the maximum sum found so far.
  • Repeat steps 1-4 for all possible column pairs.
  • The maximum sum found in step 4 represents the maximum sum subrectangle in the 2D array.
  • This approach reduces the time complexity to O(n^3).

Below is the implementation of the above approach:

C




// Program to find maximum sum subarray
// in a given 2D array
#include <limits.h>
#include <stdio.h>
#include <string.h>
#define ROW 4
#define COL 5
 
// Implementation of Kadane's algorithm
// for 1D array. The function returns the
// maximum sum and stores starting and
// ending indexes of the maximum sum subarray
// at addresses pointed by start and finish
// pointers respectively.
int kadane(int* arr, int* start, int* finish, int n)
{
    // initialize sum, maxSum and
    int sum = 0, maxSum = INT_MIN, i;
 
    // Just some initial value to check for all negative
    // values case
    *finish = -1;
 
    // local variable
    int local_start = 0;
 
    for (i = 0; i < n; ++i) {
        sum += arr[i];
        if (sum < 0) {
            sum = 0;
            local_start = i + 1;
        }
        else if (sum > maxSum) {
            maxSum = sum;
            *start = local_start;
            *finish = i;
        }
    }
 
    // There is at-least one non-negative number
    if (*finish != -1)
        return maxSum;
 
    // Special Case: When all numbers in arr[]
    // are negative
    maxSum = arr[0];
    *start = *finish = 0;
 
    // Find the maximum element in array
    for (i = 1; i < n; i++) {
        if (arr[i] > maxSum) {
            maxSum = arr[i];
            *start = *finish = i;
        }
    }
    return maxSum;
}
 
// The main function that finds maximum
// sum rectangle in
// M[][]
void findMaxSum(int M[][COL])
{
    // Variables to store the final output
    int maxSum = INT_MIN, finalLeft, finalRight, finalTop,
        finalBottom;
 
    int left, right, i;
    int temp[ROW], sum, start, finish;
 
    // Set the left column
    for (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 (right = left; right < COL; ++right) {
            // Calculate sum between current left and right
            // for every row 'i'
            for (i = 0; i < ROW; ++i)
                temp[i] += M[i][right];
 
            // Find the maximum sum subarray in temp[].
            // The kadane() function also sets values of
            // start and finish. So 'sum' is sum of
            // rectangle between (start, left) and (finish,
            // right) which is the maximum sum with
            // boundary columns strictly as left and right.
            sum = kadane(temp, &start, &finish, ROW);
 
            // Compare sum with maximum sum so far. If sum
            // is more, then update maxSum and other output
            // values
            if (sum > maxSum) {
                maxSum = sum;
                finalLeft = left;
                finalRight = right;
                finalTop = start;
                finalBottom = finish;
            }
        }
    }
 
    // Print final values
    printf("(Top, Left) (%d, %d)\n", finalTop, finalLeft);
    printf("(Bottom, Right) (%d, %d)\n", finalBottom,
        finalRight);
    printf("Max sum is: %d\n", maxSum);
}
 
// Driver Code
int main()
{
    int M[ROW][COL] = { { 1, 2, -1, -4, -20 },
                        { -8, -3, 4, 2, 1 },
                        { 3, 8, 10, 1, 3 },
                        { -4, -1, 1, 7, -6 } };
 
    // Function call
    findMaxSum(M);
 
    return 0;
}


Output

(Top, Left) (1, 1)
(Bottom, Right) (3, 3)
Max sum is: 29

Time Complexity: O(c*c*r), where c represents the number of columns and r represents the number of rows in the given matrix.
Auxiliary Space: O(r), where r represents the number of rows in the given matrix.

Please refer complete article on Maximum sum rectangle in a 2D matrix | DP-27 for more details!



Last Updated : 10 Nov, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads