# Minimum sum submatrix in a given 2D array

• Difficulty Level : Hard
• Last Updated : 04 May, 2022

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 submatrix are:
{ {1, 2, -1, -4, -20},
{-8, -3, 4, 2, 1}  } having sum = -26```

Method 1 (Naive Approach): Check every possible submatrix in a given 2D array. This solution requires 4 nested loops and the time complexity of this solution would be O(n^4).

Method 2 (Efficient Approach): Kadane’s algorithm for the 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 the sum of elements in every row from left to right and store these sums in an array say temp[]. So temp[i] indicates the 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++

 `// C++ implementation to find minimum sum``// submatrix in a given 2D array``#include ``using` `namespace` `std;` `#define ROW 4``#define COL 5` `// Implementation of Kadane's algorithm for``// 1D array. The function returns the minimum``// 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;``    ``*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;``}`

## Java

 `/*package whatever //do not write package name here */``import` `java.io.*;``import` `java.util.*;` `class` `GFG``{``    ``static` `int` `ROW = ``4``;``    ``static` `int` `COL = ``5``;``    ``static` `int` `start;``    ``static` `int` `finish;``    ` `    ``static` `int` `kadane(``int``[] arr, ``int` `n)``    ``{``      ` `        ``// initialize sum, maxSum and``        ``int` `sum = ``0``, minSum = Integer.MAX_VALUE, 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``    ``static` `void` `findMinSumSubmatrix(``int``[][] M)``    ``{``      ` `        ``// Variables to store the final output``        ``int` `minSum = Integer.MAX_VALUE;``        ``int` `finalLeft = ``0` `, finalRight = ``0``, finalTop = ``0``, finalBottom = ``0``;``        ``int` `left, right, i;``        ``int` `[]temp= ``new` `int``[ROW];``        ``int` `sum;``      ` `        ``// Set the left column``        ``for` `(left = ``0``; left < COL; ++left)``        ``{``          ` `            ``// Initialize all elements of temp as 0``            ``Arrays.fill(temp, ``0``);``            ` `            ``// 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, 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``        ``System.out.println(``"(Top, Left): ("` `+``                           ``finalTop + ``", "` `+``                           ``finalLeft + ``")"``);``        ``System.out.println(``"(Bottom, Right): ("` `+``                           ``finalBottom + ``", "` `+``                           ``finalRight + ``")"``);``        ``System.out.println(``"Minimum sum: "``+ minSum);``        ` `    ``}``  ` `    ``// Driver program to test above``    ``public` `static` `void` `main (String[] args)``    ``{``        ``int``[][] M ={{ ``1``, ``2``, -``1``, -``4``, -``20` `},``                    ``{ -``8``, -``3``, ``4``, ``2``, ``1` `},``                    ``{ ``3``, ``8``, ``10``, ``1``, ``3` `},``                    ``{ -``4``, -``1``, ``1``, ``7``, -``6` `}};``        ``findMinSumSubmatrix(M);``    ``}``}` `// This code is contributed by avanitrachhadiya2155`

## Python3

 `# Python3 implementation to find minimum``# sum submatrix in a given 2D array``import` `sys` `# Implementation of Kadane's algorithm for``# 1D array. The function returns the minimum``# sum and stores starting and ending indexes``# of the minimum sum subarray at addresses``# pointed by start and finish pointers``# respectively.``def` `kadane(arr, start, finish, n):``    ` `    ``# Initialize sum, maxSum and``    ``sum``, minSum ``=` `0``, sys.maxsize``    ` `    ``# Just some initial value to check``    ``# for all negative values case``    ``finish ``=` `-``1` `    ``# Local variable``    ``local_start ``=` `0` `    ``for` `i ``in` `range``(n):``        ``sum` `+``=` `arr[i]``        ` `        ``if` `(``sum` `> ``0``):``            ``sum` `=` `0``            ``local_start ``=` `i ``+` `1``            ` `        ``elif` `(``sum` `< minSum):``            ``minSum ``=` `sum``            ``start ``=` `local_start``            ``finish ``=` `i` `    ``# There is at-least one non-negative number``    ``if` `(finish !``=` `-``1``):``        ``return` `minSum, start, finish``        ` `    ``# Special Case: When all numbers in arr[]``    ``# are positive``    ``minSum ``=` `arr[``0``]``    ``start, finish ``=` `0``, ``0` `    ``# Find the minimum element in array``    ``for` `i ``in` `range``(``1``, n):``        ``if` `(arr[i] < minSum):``            ``minSum ``=` `arr[i]``            ``start ``=` `finish ``=` `i` `    ``return` `minSum, start, finish` `# Function to find minimum sum submatrix``# in a given 2D array``def` `findMinSumSubmatrix(M):``    ` `    ``# Variables to store the final output``    ``minSum ``=` `sys.maxsize``    ``finalLeft ``=` `0``    ``finalRight ``=` `0``    ``finalTop ``=` `0``    ``finalBottom ``=` `0``    ` `    ``#left, right, i = 0, 0, 0``    ``sum``, start, finish ``=` `0``, ``0``, ``0` `    ``# Set the left column``    ``for` `left ``in` `range``(``5``):``        ` `        ``# Initialize all elements of temp as 0``        ``temp ``=` `[``0` `for` `i ``in` `range``(``5``)]` `        ``# Set the right column for the left``        ``# column set by outer loop``        ``for` `right ``in` `range``(left, ``5``):``            ` `            ``# Calculate sum between current left``            ``# and right for every row 'i'``            ``for` `i ``in` `range``(``4``):``                ``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``, start, finish ``=` `kadane(temp, start,``                                        ``finish, ``4``)` `            ``# 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``    ``print``(``"(Top, Left): ("``, finalTop,``          ``","``, finalLeft, ``")"``)``    ``print``(``"(Bottom, Right): ("``, finalBottom,``          ``","``, finalRight, ``")"``)``    ``print``(``"Minimum sum:"``, minSum)` `# Driver code``if` `__name__ ``=``=` `'__main__'``:` `    ``M ``=` `[ [ ``1``, ``2``, ``-``1``, ``-``4``, ``-``20` `],``          ``[ ``-``8``, ``-``3``, ``4``, ``2``, ``1` `],``          ``[ ``3``, ``8``, ``10``, ``1``, ``3` `],``          ``[ ``-``4``, ``-``1``, ``1``, ``7``, ``-``6` `] ]` `    ``findMinSumSubmatrix(M)` `# This code is contributed by mohit kumar 29`

## C#

 `using` `System;``public` `class` `GFG``{``    ``static` `int` `ROW = 4;``    ``static` `int` `COL = 5;``    ``static` `int` `start;``    ``static` `int` `finish;``    ``static` `int` `kadane(``int``[] arr, ``int` `n)``    ``{``      ` `        ``// initialize sum, maxSum and``        ``int` `sum = 0, minSum = Int32.MaxValue, 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;``        ``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``    ``static` `void` `findMinSumSubmatrix(``int``[,] M)``    ``{``      ` `        ``// Variables to store the final output``        ``int` `minSum = Int32.MaxValue;``        ``int` `finalLeft = 0 , finalRight = 0, finalTop = 0, finalBottom = 0;``        ``int` `left, right, i;``        ``int` `[]temp= ``new` `int``[ROW];``        ``int` `sum;``        ` `        ``// Set the left column``        ``for` `(left = 0; left < COL; ++left)``        ``{``           ` `            ``// Initialize all elements of temp as 0``            ``Array.Fill(temp, 0);``             ` `            ``// 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, 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;``                ``}``            ``}``             ` `        ``}``        ``Console.WriteLine(``"(Top, Left): ("` `+``                          ``finalTop + ``", "` `+``                          ``finalLeft + ``")"``);``        ``Console.WriteLine(``"(Bottom, Right): ("` `+``                          ``finalBottom + ``", "` `+``                          ``finalRight + ``")"``);``        ``Console.WriteLine(``"Minimum sum: "``+ minSum);``    ``}``  ` `    ``// Driver program to test above``    ``static` `public` `void` `Main ()``    ``{``        ``int``[,] M ={{ 1, 2, -1, -4, -20 },``                   ``{ -8, -3, 4, 2, 1 },``                   ``{ 3, 8, 10, 1, 3 },``                   ``{ -4, -1, 1, 7, -6 }};``        ``findMinSumSubmatrix(M);``    ``}``}` `// This code is contributed by rag2127`

## Javascript

 ``

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 write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.