Largest Submatrix With Sum 0
Last Updated :
13 Jan, 2025
Given a 2D matrix of dimension n x m, the task is to find the area of largest submatrix whose sum is 0.
Examples:
Input: mat[][] = [[9, 7, 16, 5], [1, -6, -7, 3], [1, 8, 7, 9], [7, -2, 0, 10]]
Output: 6
Explanation:
Input: mat[][] = [[1, 2, 3], [-3, -2, -1], [1, 7, 5]]
Output: 6
Explanation:
Input: mat[][] = [[1, -1], [-1, 1]]
Output: 4
Explanation: The largest submatrix with sum 0 is [[1, -1], [-1, 1]].
[Naive Approach] Using four Nested Loops - O(n^4) Time and O(n^2) Space
The naive solution for this problem is to check the sum of every possible rectangle in given 2D array. For this we can use four nested loop to fix the upper row, bottom row, left column and right column of the sub matrix.
Now for each such sub matrix we can find its sum using a 2D prefix sum matrix in constant time. If this calculated sum is equal to 0 then update the maximum area found.
[Expected Approach] Using Prefix Sum - O(n^3) Time and O(n) Space
The idea is to iterate over all pairs of rows to fix the top and bottom row (or height) of the 0-sum submatrix. Let's see how to get the width of the largest submatrix with 0-sum.
To find the width of largest submatrix with zero sum for a given top and bottom row pair:
- For a given top-bottom pair, we compute the column-wise cumulative sum in a temporary array
temp[]
. - Now find the length of Longest Subarray with 0 Sum in temp[] array.
The Length of longest Subarray with 0 Sum in temp[] array will also be the width of the largest 0-sum submatrix.
C++
// C++ program to find Largest rectangular
// sub-matrix whose sum is 0
#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;
int maxZeroSumSubarray(vector<int> &arr) {
int prefSum = 0;
int maxLength = 0;
// Hash map to store the first index of each prefix sum
unordered_map<int, int> mp;
// Iterate through the array to find subarrays with zero sum
for (int i = 0; i < arr.size(); i++) {
prefSum += arr[i];
if (prefSum == 0)
maxLength = i+1;
if (mp.find(prefSum) != mp.end()) {
// If this prefSum repeats, find subarray length.
maxLength = max(maxLength, (i - mp[prefSum]));
}
else {
// Only store the index of the first occurrence of prefSum
mp[prefSum] = i;
}
}
return maxLength;
}
int zeroSumSubmat(vector<vector<int>> &mat) {
int rows = mat.size();
int cols = mat[0].size();
int maxArea = 0;
for (int i = 0; i < rows; i++) {
// Temporary array to store the column-wise cumulative sum
vector<int> temp(cols, 0);
// Iterate over each row from i to j
for (int j = i; j < rows; j++) {
// Accumulate the column-wise sum for rows between i and j
for (int k = 0; k < cols; k++)
temp[k] += mat[j][k];
// Find the longest zero-sum subarray in column sums
int len = maxZeroSumSubarray(temp);
// Update the maximum area
maxArea = max(maxArea, (j - i + 1) * len);
}
}
return maxArea;
}
int main() {
vector<vector<int>> mat = {{9, 7, 16, 5},
{1, -6, -7, 3},
{1, 8, 7, 9},
{7, -2, 0, 10}
};
cout << zeroSumSubmat(mat) << endl;
return 0;
}
Java
// Java program to find Largest rectangular
// sub-matrix whose sum is 0
import java.util.HashMap;
class GfG {
// Function to find the largest zero-sum subarray
static int maxZeroSumSubarray(int[] arr) {
int prefSum = 0;
int maxLength = 0;
// Hash map to store the first index of each prefix sum
HashMap<Integer, Integer> mp = new HashMap<>();
// Iterate through the array to find subarrays with zero sum
for (int i = 0; i < arr.length; i++) {
prefSum += arr[i];
if (prefSum == 0)
maxLength = i + 1;
if (mp.containsKey(prefSum)) {
// If this prefSum repeats, find subarray length.
maxLength = Math.max(maxLength, (i - mp.get(prefSum)));
} else {
// Only store the index of the first occurrence of prefSum
mp.put(prefSum, i);
}
}
return maxLength;
}
static int zeroSumSubmat(int[][] mat) {
int rows = mat.length;
int cols = mat[0].length;
int maxArea = 0;
for (int i = 0; i < rows; i++) {
// Temporary array to store the column-wise cumulative sum
int[] temp = new int[cols];
// Iterate over each row from i to j
for (int j = i; j < rows; j++) {
// Accumulate the column-wise sum for rows between i and j
for (int k = 0; k < cols; k++)
temp[k] += mat[j][k];
// Find the longest zero-sum subarray in column sums
int len = maxZeroSumSubarray(temp);
// Update the maximum area
maxArea = Math.max(maxArea, (j - i + 1) * len);
}
}
return maxArea;
}
public static void main(String[] args) {
int[][] mat = {
{9, 7, 16, 5},
{1, -6, -7, 3},
{1, 8, 7, 9},
{7, -2, 0, 10}
};
System.out.println(zeroSumSubmat(mat));
}
}
Python
# Python program to find Largest rectangular
# sub-matrix whose sum is 0
def maxZeroSumSubarray(arr):
prefSum = 0
maxLength = 0
# Hash map to store the first index of each prefix sum
mp = {}
# Iterate through the array to find subarrays with zero sum
for i in range(len(arr)):
prefSum += arr[i]
if prefSum == 0:
maxLength = i + 1
if prefSum in mp:
# If this prefSum repeats, find subarray length.
maxLength = max(maxLength, i - mp[prefSum])
else:
# Only store the index of the first occurrence of prefSum
mp[prefSum] = i
return maxLength
def zeroSumSubmat(mat):
rows = len(mat)
cols = len(mat[0])
maxArea = 0
for i in range(rows):
# Temporary array to store the column-wise cumulative sum
temp = [0] * cols
# Iterate over each row from i to j
for j in range(i, rows):
# Accumulate the column-wise sum for rows between i and j
for k in range(cols):
temp[k] += mat[j][k]
# Find the longest zero-sum subarray in column sums
lenSubarray = maxZeroSumSubarray(temp)
# Update the maximum area
maxArea = max(maxArea, (j - i + 1) * lenSubarray)
return maxArea
if __name__ == '__main__':
mat = [
[9, 7, 16, 5],
[1, -6, -7, 3],
[1, 8, 7, 9],
[7, -2, 0, 10]
]
print(zeroSumSubmat(mat))
C#
// C# program to find Largest rectangular
// sub-matrix whose sum is 0
using System;
using System.Collections.Generic;
class GfG {
// Function to find the largest zero-sum subarray
static int maxZeroSumSubarray(int[] arr) {
int prefSum = 0;
int maxLength = 0;
// Hash map to store the first index of each prefix sum
Dictionary<int, int> mp = new Dictionary<int, int>();
// Iterate through the array to find subarrays with zero sum
for (int i = 0; i < arr.Length; i++) {
prefSum += arr[i];
if (prefSum == 0)
maxLength = i + 1;
if (mp.ContainsKey(prefSum)) {
// If this prefSum repeats, find subarray length.
maxLength = Math.Max(maxLength, i - mp[prefSum]);
} else {
// Only store the index of the first occurrence of prefSum
mp[prefSum] = i;
}
}
return maxLength;
}
static int zeroSumSubmat(int[][] mat) {
int rows = mat.Length;
int cols = mat[0].Length;
int maxArea = 0;
for (int i = 0; i < rows; i++) {
// Temporary array to store the column-wise cumulative sum
int[] temp = new int[cols];
// Iterate over each row from i to j
for (int j = i; j < rows; j++) {
// Accumulate the column-wise sum for rows between i and j
for (int k = 0; k < cols; k++)
temp[k] += mat[j][k];
// Find the longest zero-sum subarray in column sums
int len = maxZeroSumSubarray(temp);
// Update the maximum area
maxArea = Math.Max(maxArea, (j - i + 1) * len);
}
}
return maxArea;
}
static void Main() {
int[][] mat = {
new int[] {9, 7, 16, 5},
new int[] {1, -6, -7, 3},
new int[] {1, 8, 7, 9},
new int[] {7, -2, 0, 10}
};
Console.WriteLine(zeroSumSubmat(mat));
}
}
JavaScript
// JavaScript program to find Largest rectangular
// sub-matrix whose sum is 0
function maxZeroSumSubarray(arr) {
let prefSum = 0;
let maxLength = 0;
// Hash map to store the first index of each prefix sum
const mp = new Map();
// Iterate through the array to find subarrays with zero sum
for (let i = 0; i < arr.length; i++) {
prefSum += arr[i];
if (prefSum === 0)
maxLength = i + 1;
if (mp.has(prefSum)) {
// If this prefSum repeats, find subarray length
maxLength = Math.max(maxLength, i - mp.get(prefSum));
} else {
// Only store the index of the first occurrence of prefSum
mp.set(prefSum, i);
}
}
return maxLength;
}
function zeroSumSubmat(mat) {
const rows = mat.length;
const cols = mat[0].length;
let maxArea = 0;
for (let i = 0; i < rows; i++) {
// Temporary array to store the column-wise cumulative sum
const temp = Array(cols).fill(0);
// Iterate over each row from i to j
for (let j = i; j < rows; j++) {
// Accumulate the column-wise sum for rows between i and j
for (let k = 0; k < cols; k++)
temp[k] += mat[j][k];
// Find the longest zero-sum subarray in column sums
const len = maxZeroSumSubarray(temp);
// Update the maximum area
maxArea = Math.max(maxArea, (j - i + 1) * len);
}
}
return maxArea;
}
// Driver Code
const mat = [
[9, 7, 16, 5],
[1, -6, -7, 3],
[1, 8, 7, 9],
[7, -2, 0, 10]
];
console.log(zeroSumSubmat(mat));
Similar Reads
Longest Subarray with 0 Sum Given an array arr[] of size n, the task is to find the length of the longest subarray with sum equal to 0.Examples:Input: arr[] = {15, -2, 2, -8, 1, 7, 10, 23}Output: 5Explanation: The longest subarray with sum equals to 0 is {-2, 2, -8, 1, 7}Input: arr[] = {1, 2, 3}Output: 0Explanation: There is n
10 min read
Submatrix with corners as 1 Given a binary matrix containing only 0s and 1s. The task is to check whether there exists a rectangle or square submatrix of size at least 2 Ã 2 such that all four corners of that submatrix are 1.This means we must find four positions in the matrix (top-left, top-right, bottom-left, and bottom-righ
15+ min read
Largest sub-matrix with all equal elements Given a binary matrix of size N * M, the task is to find the largest area sub-matrix such that all elements in it are same i.e. either all are 0 or all are 1. Print the largest possible area of such matrix. Examples: Input: mat[][] = { {1, 1, 0, 1, 0, 0, 0, 0}, {0, 1, 1, 1, 1, 0, 0, 1}, {1, 0, 0, 1,
15+ min read
Square submatrices with odd boundary sum Given an integer N. The task is to generate a square matrix of (N x N) with the following conditions: The elements of the matrix should be distinct and range from 1 to N*N.The boundary sum of all square sub-matrices starting from A (0, 0) is odd. In other words, we have to generate a square matrix h
6 min read
Largest sum Zigzag sequence in a matrix Given a matrix of size n x n, find the sum of the Zigzag sequence with the largest sum. A zigzag sequence starts from the top and ends at the bottom. Two consecutive elements of sequence cannot belong to the same column. Examples: Input : mat[][] = 3 1 2 4 8 5 6 9 7Output : 18Zigzag sequence is: 3-
15+ min read
Maximum sum submatrix Prerequisite: Kadane's algorithm Given a 2D array arr[][] of dimension N*M, the task is to find the maximum sum sub-matrix from the matrix arr[][]. Examples: Input: arr[][] = {{0, -2, -7, 0 }, { 9, 2, -6, 2 }, { -4, 1, -4, 1 }, { -1, 8, 0, -2}}Output: 15Explanation: The submatrix {{9, 2}, {-4, 1}, {
15+ min read
Largest possible square submatrix with maximum AND value Given an integer matrix mat [ ][ ] dimensions, the task is to find the largest possible square matrix from the given matrix with maximum AND value. AND value of a matrix is defined as the value obtained after performing bitwise AND operation on all elements of the matrix. Examples: Input: mat [ ][ ]
13 min read
Smallest submatrix with Kth maximum XOR Given a matrix m[][] of dimensions N Ã M and an integer K, calculate XOR(i, j) which is equal to the Bitwise Xor of all elements of submatrix from indices (1, 1) to (i, j)), for every index of the matrix. The task is to find the submatrix {(1, 1), ..., (i, j)} having Kth maximum XOR(i, j) value. If
9 min read
Find Matrix With Given Row and Column Sums Given two arrays rowSum[] and colSum[] of size n and m respectively, the task is to construct a matrix of dimensions n à m such that the sum of matrix elements in every ith row is rowSum[i] and the sum of matrix elements in every jth column is colSum[j].Note: The resultant matrix can have only non-n
15 min read