给定一个矩阵mat[][] ,其元素按行和列排序。任务是从给定的矩阵mat[][] 中找到任何子矩阵的最大和。
例子:
Input: mat[][] = { {-6, -4, -1}, {-3, 2, 4}, {2, 5, 8}}
Output: 19
Explanation:
The largest submatrix is given by:
2 4
5 8
Input: mat[][] = { {-4, -3}, {-2, -1} }
Output: -1
Explanation:
The sub matrix consisting of the last element i.e., -1 has the largest sum possible.
朴素的方法:这个想法是使用 Kadane 算法在 2D 矩阵中找到最大和矩形。打印获得的最大和。
时间复杂度: O(N 2 *M 2 ),其中 N 是行数,M 是列数
辅助空间: O(N)
有效方法:思想是从给定矩阵的底部单元格中找到最大和,并使用动态规划来存储来自底部单元格的任何子矩阵的最大和。以下是步骤:
- 创建一个大小为NxM的 dp 表dp[][]来存储从每个单元格(i, j)开始的子矩阵的最大和。
- 找到从右下角的单元格(N, M)开始向上和向左的子矩阵的总和,并不断将最大总和更新为dp[][] 。
- 由于矩阵按 Row-Wise 和 Column-Wise 排序,因此最大的子矩阵总和可以从任何点开始,但肯定会在右下角的单元格 (N, M) 处结束。
- 下面是 dp 表的填充关系:
DP[i][j] = DP[i+1][j] + DP[i][j+1] – DP[i+1][j+1]
- 因此,在 dp 表中找到最大元素。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function that finds the maximum
// Sub-Matrix Sum
int maxSubMatSum(vector > mat)
{
// Number of rows in the matrix
int n = mat.size();
// Number of columns in the matrix
int m = mat[0].size();
int i, j;
// dp[][] matrix to store the
// results of each iteration
int dp[n][m];
// Base Case - The largest
// element in the matrix
dp[n - 1][m - 1] = mat[n - 1][m - 1];
// To stores the final result
int res = dp[n - 1][m - 1];
// Find the max sub matrix sum for
// the last row
for (i = m - 2; i >= 0; i--) {
dp[n - 1][i] = mat[n - 1][i]
+ dp[n - 1][i + 1];
// Check whether the current
// sub-array yields maximum sum
res = max(res, dp[n - 1][i]);
}
// Calculate the max sub matrix
// sum for the last column
for (i = n - 2; i >= 0; i--) {
dp[i][m - 1] = mat[i][m - 1]
+ dp[i + 1][m - 1];
// Check whether the current
// sub-array yields maximum sum
res = max(res, dp[i][m - 1]);
}
// Build the dp[][] matrix from
// bottom to the top row
for (i = n - 2; i >= 0; i--) {
for (j = m - 2; j >= 0; j--) {
// Update sum at each
// cell in dp[][]
dp[i][j]
= mat[i][j] + dp[i][j + 1]
+ dp[i + 1][j]
- dp[i + 1][j + 1];
// Update the maximum sum
res = max(res, dp[i][j]);
}
}
// Return the maximum sum
return res;
}
// Driver Code
int main()
{
// Given matrix mat[][]
vector > mat;
mat = { { -6, -4, -1 },
{ -3, 2, 4 },
{ 2, 5, 8 } };
// Function Call
cout << maxSubMatSum(mat);
return 0;
}
Java
// Java program for the above approach
class GFG{
// Function that finds the maximum
// Sub-Matrix Sum
static int maxSubMatSum(int [][]mat)
{
// Number of rows in the matrix
int n = mat.length;
// Number of columns in the matrix
int m = mat[0].length;
int i, j;
// dp[][] matrix to store the
// results of each iteration
int [][]dp = new int[n][m];
// Base Case - The largest
// element in the matrix
dp[n - 1][m - 1] = mat[n - 1][m - 1];
// To stores the final result
int res = dp[n - 1][m - 1];
// Find the max sub matrix sum for
// the last row
for (i = m - 2; i >= 0; i--)
{
dp[n - 1][i] = mat[n - 1][i] +
dp[n - 1][i + 1];
// Check whether the current
// sub-array yields maximum sum
res = Math.max(res, dp[n - 1][i]);
}
// Calculate the max sub matrix
// sum for the last column
for (i = n - 2; i >= 0; i--)
{
dp[i][m - 1] = mat[i][m - 1] +
dp[i + 1][m - 1];
// Check whether the current
// sub-array yields maximum sum
res = Math.max(res, dp[i][m - 1]);
}
// Build the dp[][] matrix from
// bottom to the top row
for (i = n - 2; i >= 0; i--)
{
for (j = m - 2; j >= 0; j--)
{
// Update sum at each
// cell in dp[][]
dp[i][j] = mat[i][j] + dp[i][j + 1] +
dp[i + 1][j] - dp[i + 1][j + 1];
// Update the maximum sum
res = Math.max(res, dp[i][j]);
}
}
// Return the maximum sum
return res;
}
// Driver Code
public static void main(String[] args)
{
// Given matrix mat[][]
int [][]mat= {{ -6, -4, -1 },
{ -3, 2, 4 },
{ 2, 5, 8 } };
// Function Call
System.out.print(maxSubMatSum(mat));
}
}
// This code is contributed by Rohit_ranjan
Python3
# Python3 program for the above approach
# Function that finds the maximum
# Sub-Matrix Sum
def maxSubMatSum(mat):
# Number of rows in the matrix
n = len(mat)
# Number of columns in the matrix
m = len(mat[0])
# dp[][] matrix to store the
# results of each iteration
dp = [[0] * m for _ in range(n)]
# Base Case - The largest
# element in the matrix
dp[n - 1][m - 1] = mat[n - 1][m - 1]
# To stores the final result
res = dp[n - 1][m - 1]
# Find the max sub matrix sum for
# the last row
for i in range(m - 2, -1, -1):
dp[n - 1][i] = (mat[n - 1][i] +
dp[n - 1][i + 1])
# Check whether the current
# sub-array yields maximum sum
res = max(res, dp[n - 1][i])
# Calculate the max sub matrix
# sum for the last column
for i in range(n - 2, -1, -1):
dp[i][m - 1] = (mat[i][m - 1] +
dp[i + 1][m - 1])
# Check whether the current
# sub-array yields maximum sum
res = max(res, dp[i][m - 1])
# Build the dp[][] matrix from
# bottom to the top row
for i in range(n - 2, -1, -1):
for j in range(m - 2, -1, -1):
# Update sum at each
# cell in dp[][]
dp[i][j] = (mat[i][j] +
dp[i][j + 1] +
dp[i + 1][j]-
dp[i + 1][j + 1])
# Update the maximum sum
res = max(res, dp[i][j])
# Return the maximum sum
return res
# Driver Code
if __name__ == '__main__':
# Given matrix mat[][]
mat = [ [ -6, -4, -1 ],
[ -3, 2, 4 ],
[ 2, 5, 8 ] ]
# Function call
print(maxSubMatSum(mat))
# This code is contributed by mohit kumar 29
C#
// C# program for the above approach
using System;
class GFG{
// Function that finds the maximum
// Sub-Matrix Sum
static int maxSubMatSum(int [,]mat)
{
// Number of rows in the matrix
int n = mat.GetLength(0);
// Number of columns in the matrix
int m = mat.GetLength(1);
int i, j;
// [,]dp matrix to store the
// results of each iteration
int [,]dp = new int[n, m];
// Base Case - The largest
// element in the matrix
dp[n - 1, m - 1] = mat[n - 1, m - 1];
// To stores the readonly result
int res = dp[n - 1, m - 1];
// Find the max sub matrix sum for
// the last row
for (i = m - 2; i >= 0; i--)
{
dp[n - 1, i] = mat[n - 1, i] +
dp[n - 1, i + 1];
// Check whether the current
// sub-array yields maximum sum
res = Math.Max(res, dp[n - 1,i]);
}
// Calculate the max sub matrix
// sum for the last column
for (i = n - 2; i >= 0; i--)
{
dp[i, m - 1] = mat[i, m - 1] +
dp[i + 1, m - 1];
// Check whether the current
// sub-array yields maximum sum
res = Math.Max(res, dp[i, m - 1]);
}
// Build the [,]dp matrix from
// bottom to the top row
for (i = n - 2; i >= 0; i--)
{
for (j = m - 2; j >= 0; j--)
{
// Update sum at each
// cell in [,]dp
dp[i, j] = mat[i, j] + dp[i, j + 1] +
dp[i + 1, j] - dp[i + 1, j + 1];
// Update the maximum sum
res = Math.Max(res, dp[i, j]);
}
}
// Return the maximum sum
return res;
}
// Driver Code
public static void Main(String[] args)
{
// Given matrix [,]mat
int [,]mat= {{ -6, -4, -1 },
{ -3, 2, 4 },
{ 2, 5, 8 } };
// Function Call
Console.Write(maxSubMatSum(mat));
}
}
// This code is contributed by Rohit_ranjan
Javascript
输出:
19
时间复杂度: O(N*M),其中 N 是行数,M 是列数
辅助空间: O(N*M)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。