📜  按行和列排序的矩阵的任何子矩阵的最大和

📅  最后修改于: 2021-05-17 20:35:22             🧑  作者: Mango

给定一个矩阵mat [] [],其元素按行和列进行排序。任务是从给定的矩阵mat [] []中找到任何子矩阵的最大和。

例子:

天真的方法:这个想法是使用Kadane算法在2D矩阵中找到最大和矩形。打印获得的最大金额。

时间复杂度: O(N 2 * M 2 ),其中N是行数,M是列数
辅助空间: O(N)
高效方法:想法是从给定矩阵的底部单元中找到最大和,并使用动态编程存储底部单元中任何子矩阵的最大和。步骤如下:

  1. 创建大小为NxM的dp表dp [] [] ,以存储从每个像元(i,j)开始的子矩阵的最大和。
  2. 找到从右下角的单元格(N,M)开始和向左移动的子矩阵的总和,然后将最大总和更新为dp [] []
  3. 由于矩阵按行明智和列明智排序,因此最大的子矩阵和可以从任何点开始,但肯定会在右下角的单元格(N,M)上结束。
  4. 以下是dp表的填充关系:
  5. 因此,在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 yeilds 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 yeilds 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 yeilds 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 yeilds 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 yeilds 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 yeilds 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 yeilds 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 yeilds 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


输出:
19




时间复杂度: O(N * M),其中N是行数,M是列数
辅助空间: O(N * M)