Hi ๐, I'm a software engineer specializing in backend systems, distributed systems, and scalable architecture. My blog shares practical tutorials based on 3+ years of experience. LeetCode 1756 (Top 10%). Actively seeking SDE roles โ let's get in touch!
Comments
Leave a Comment
Success!
Receive Latest Updates ๐ฌ
Get every new post, special offers, and more via email. No fee required.
Maximum subarray sum and maximum submatrix sum are common dynamic programming problems in many programming contests.
In this tutorial, I will show you how to solve the maximum submatrix sum problem using Kadane's Algorithm.
I will also explain the intuition behind Kadane's Algorithm and provide code implementations in C++, JavaScript, and Python.
Kadane's Algorithm is a dynamic programming algorithm that is used to find the maximum sum of a subarray in a 1D array and can be extended to 2D matrices (which I will explain later).
The algorithm is named after its inventor, Jay Kadane, who developed it in 1984. Until now, it is still a common algorithm that appears in a lot of programming problems.
The problem is given below. Consider the example matrix in the image and its green submatrix with a total sum of 15 (and also the maximum sum of all submatrices in the example matrix).
Figure: Maximum Submatrix Sum
How do we find that green matrix? That's where Kadane's Algorithm comes in.
Before diving into Kadane's Algorithm for 2D matrices, let's first look at how it works for 1D arrays.
Kadaneโs algorithm is commonly used to find the maximum subarray sum in a 1D array in O(n) time complexity.
Problem: Given an array of integers, find the maximum sum of a subarray.
Example: Given the array [2, 1, 0, 3, -4, 5], the maximum sum of a subarray is 7, which is the sum of the subarray [0, 3, -4, 5].
Steps to Solve:
Create the sum variable to store the sum of the current subarray and initialize it to 0.
Create the ans variable to store the maximum sum of a subarray and initialize it to 0.
Iterate through the array and add each element to the sum variable.
If the sum variable is greater than the ans variable, update the ans variable.
If the sum variable is less than 0, reset it to 0.
Return the ans variable.
kadanes-algorithm-1d.cpp
#include <iostream>using namespace std;int main() { int n; cin >> n; int a[n]; for (int i = 0; i < n; i++) cin >> a[i]; int sum = 0, ans = 0; for (int i = 0; i < n; i++) { sum += a[i]; if (sum > ans) ans = sum; if (sum < 0) sum = 0; } cout << ans; return 0;}
Then, we can apply Kadane's Algorithm to find the maximum sum of a subarray in each of these 1D arrays.
Finally, we can take the maximum of all these sums to get the maximum sum of a submatrix.
Step 1 takes O(nm) time. Step 2 takes O(n) time as we can use prefix sum to calculate the sum of each row in O(1) time. In overall, the time complexity of Kadane's Algorithm for 2D matrices is O(nm2).
Here is the code in C++:
kadanes-algorithm-2d.cpp
// Calculate prefix sumfor (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { cin >> a[i][j]; if (j > 0) a[i][j] += a[i][j - 1]; // prefix sum for i-th row }}// Kadane's algorithm for 2D arrayint ans = 0;for (int i = 0; i < m; i++) { // from i for (int j = i + 1; j < m; j++) { // to j int sum = 0; for (int k = 0; k < n; k++) { // iterate from first row to last row sum += a[k][j]; if (i > 0) sum -= a[k][i - 1]; if (sum > ans) ans = sum; if (sum < 0) sum = 0; } }}
Next, we iterate through all possible pairs of columns (i, j) and apply Kadane's Algorithm to the subarray between columns i and j. For example, when i=0 and j=2, the subarray looks like this:
text
1 2 -1-8 -3 4 3 8 10-4 -1 1
We apply Kadane's Algorithm to this subarray, starting with an empty subarray and accumulating elements until the sum becomes negative. When the sum is negative, we reset it to 0 and continue accumulating. At each step, we keep track of the maximum sum we have seen so far. Applying Kadane's Algorithm to the subarray above, we get a maximum sum of 21.
We repeat this process for all pairs of columns and keep track of the maximum sum we find. In this case, the maximum sum is 29, which occurs in the submatrix:
text
10 1 3 1 7 -6
Overall, Kadane's Algorithm allows us to efficiently find the maximum sum of a rectangular submatrix in a 2D matrix.
#include<bits/stdc++.h>using namespace std;int main() { int n; cin >> n; vector<int> a(n); for(int i = 0; i < n; i++) cin >> a[i]; int sum = 0, ans = 0; for(int i = 0; i < n; i++){ sum += a[i]; ans = max(ans, sum); if (sum < 0) sum = 0; } cout << ans; return 0;}
#include<bits/stdc++.h>using namespace std;int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int n, m; cin >> n >> m; vector<vector<int> > a(n, vector<int>(m)); for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { cin >> a[i][j]; if (j > 0) a[i][j] += a[i][j - 1]; // prefix sum for i-th row } } int ans = 0; for (int i = 0; i < m; i++) { for (int j = i + 1; j < m; j++) { int sum = 0; for (int k = 0; k < n; k++) { // iterate from first row sum += a[k][j]; if (i > 0) sum -= a[k][i - 1]; ans = max(ans, sum); if (sum < 0) sum = 0; } } } cout << ans; return 0;}
def kadanes_algorithm_2d(matrix): rows, cols = len(matrix), len(matrix[0]) max_sum = float('-inf') for left in range(cols): row_sums = [0] * rows for right in range(left, cols): for i in range(rows): row_sums[i] += matrix[i][right] current_sum = 0 max_ending_here = float('-inf') for i in range(rows): current_sum += row_sums[i] max_ending_here = max(max_ending_here + row_sums[i], row_sums[i]) max_sum = max(max_sum, max_ending_here, current_sum) return max_sum
Comments