Given a 2D array, find the minimum sum submatrix in it.
Examples:
Input : M[][] = {{1, 2, -1, -4, -20},
{-8, -3, 4, 2, 1},
{3, 8, 10, 1, 3},
{-4, -1, 1, 7, -6}}
Output : -26
Submatrix starting from (Top, Left): (0, 0)
and ending at (Bottom, Right): (1, 4) indexes.
The elements are of the submtrix are:
{ {1, 2, -1, -4, -20},
{-8, -3, 4, 2, 1} } having sum = -26
Method 1 (Naive Approach): Check every possible submatrix in given 2D array. This solution requires 4 nested loops and time complexity of this solution would be O(n^4).
Method 2 (Efficient Approach): Kadane’s algorithm for 1D 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 minimum sum contiguous rows for every left and right column pair. We basically find top and bottom row numbers (which have minimum sum) for every fixed left and right column pair. To find the top and bottom row numbers, calculate sun 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. If we apply Kadane’s 1D algorithm on temp[], and get the minimum sum subarray of temp, this minimum sum would be the minimum possible sum with left and right as boundary columns. To get the overall minimum sum, we compare this sum with the minimum sum so far.
// C++ implementation to find minimum sum // submatrix in a given 2D array #include <bits/stdc++.h> using namespace std; #define ROW 4 #define COL 5 // Implementation of Kadane's algorithm for // 1D array. The function returns the miniimum // sum and stores starting and ending indexes // of the minimum 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, minSum = INT_MAX, 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 < minSum) { minSum = sum; *start = local_start; *finish = i; } } // There is at-least one non-negative number if (*finish != -1) return minSum; // Special Case: When all numbers in arr[] // are positive minSum = arr[0]; *start = *finish = 0; // Find the minimum element in array for (i = 1; i < n; i++) { if (arr[i] < minSum) { minSum = arr[i]; *start = *finish = i; } } return minSum; } // function to find minimum sum submatrix // in a given 2D array void findMinSumSubmatrix(int M[][COL]) { // Variables to store the final output int minSum = INT_MAX, 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 minimum 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 minimum 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 < minSum) { minSum = sum; finalLeft = left; finalRight = right; finalTop = start; finalBottom = finish; } } } // Print final values cout << "(Top, Left): (" << finalTop << ", " << finalLeft << ")\n"; cout << "(Bottom, Right): (" << finalBottom << ", " << finalRight << ")\n"; cout << "Minimum sum: " << minSum; } // Driver program to test above 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 } }; findMinSumSubmatrix(M); return 0; } |
Output:
(Top, Left): (0, 0) (Bottom, Right): (1, 4) Minimum sum: -26
Time Complexity: O(n^3)
This article is contributed by Ayush Jauhari. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.
Recommended Posts:
- Count of submatrix with sum X in a given Matrix
- Bitwise XOR of a submatrix of a matrix generated from a given array
- Minimum cells to be flipped to get a 2*2 submatrix with equal elements
- Submatrix Sum Queries
- Find Maximum Length Of A Square Submatrix Having Sum Of Elements At-Most K
- Maximum sum of any submatrix of a Matrix which is sorted row-wise and column-wise
- Submatrix of given size with maximum 1's
- Summed Area Table - Submatrix Summation
- Maximize the binary matrix by filpping submatrix once
- Smallest submatrix with Kth maximum XOR
- Maximum value in a matrix which contain intersecting concentric submatrix
- XOR of a submatrix queries
- Check if matrix A can be converted to B by changing parity of corner elements of any submatrix
- Check if a matrix contains a square submatrix with 0 as boundary element
- Largest possible square submatrix with maximum AND value
- Flip minimum signs of array elements to get minimum sum of positive elements possible
- Minimum cost required to rearrange a given array to make it equal to another given array
- Minimum possible sum of prices of a Triplet from the given Array
- Maximum sum subarray having sum less than or equal to given sum using Set
- Count of Ways to obtain given Sum from the given Array elements

