【问题标题】:Maximum sized square sub-matrix最大尺寸平方子矩阵
【发布时间】:2018-10-13 17:19:11
【问题描述】:

我有一个大小为 N*M 的矩阵,其中填充了 0 和 1。 对于每个查询 K,我必须回答最大尺寸的方形子矩阵,其中最小值(1 的数量,0 的数量)=k,其中 1

10000000
01000000
00000000
00000000
00000000
00000000
00000000
00000000



k= 1        answer= 7
k=2         answer= 8
k=0         answer= 6
k=1001      answer= 8

我知道对于 k=1,子矩阵 (1,1) 到 (7,7) 适用于 k=2,最大的方形子矩阵是原始矩阵本身。 对于 k=1,我们必须得到所有的 7*7 平方子矩阵。找到他们的最小值(1 的数量,0 的数量),然后得到所有这些中的最小值作为答案。

我无法生成所有的平方子矩阵对。谁能帮助我实现这一目标?此外,如果有任何更短的方法可用,那也很好,因为这需要很长时间。

【问题讨论】:

    标签: c matrix dynamic-programming submatrix


    【解决方案1】:

    这是一个面试问题吗?这个问题与最大子矩阵和 (https://www.geeksforgeeks.org/maximum-sum-rectangle-in-a-2d-matrix-dp-27/) 的问题非常相似,你应该能够适应它的 DP 解决方案。

    编辑:

    以下是O(n^3)时间O(n^2)内存 要实现的重要部分是区域 D = 整个区域 - B - C + A

    | A B |
    | C D |
    
    #include <stdlib.h>
    #include <stdio.h>
    
    int **create_dp(int **matrix, int **dp, int row, int col) {
      dp[0][0] = matrix[0][0];
      for (int i = 1; i < row; ++i) 
        dp[i][0] = matrix[i][0] + dp[i - 1][0];
      for (int j = 1; j < col; ++j) 
        dp[0][j] = matrix[0][j] + dp[0][j - 1];
      for (int i = 1; i < row; ++i) 
        for (int j = 1; j < col; ++j) 
          dp[i][j] = dp[i - 1][j] + dp[i][j - 1] + matrix[i][j] - dp[i - 1][j - 1];
    }
    
    int min(int x, int y) { 
      if (x > y) return y;
      return x;
    }
    
    int max_square_submatrix(int **matrix, int row, int col, int query) {
      // the value dp[i][j] is the sum of all values in matrix up to i, j 
      // i.e. dp[1][1] = matrix[0][0] + matrix[1][0] + matrix[0][1] + matrix[1][1]
      int **dp = malloc(sizeof(int*) * row);
      for (int i = 0; i < row; ++i) dp[i] = malloc(sizeof(int) * col);
      create_dp(matrix, dp, row, col);
      int global_max_size = 0;
      // go through all squares in matrix
      for (int i = 0; i < row; ++i) {
        for (int j = 0; j < col; ++j) {
          // begin creating square matrices
          // this is the largest size a square matrix could have
          int max_size = min(row - i, col - j) - 1;
          for (; max_size >= 0; --max_size) {
            // you need to see above diagram in order to visualize this step
            int num_ones = dp[i + max_size][j + max_size];
            if (i > 0 && j > 0)
              num_ones += -dp[i + max_size][j - 1] - dp[i - 1][j + max_size] + dp[i - 1][j - 1];
            else if (j > 0)
              num_ones += -dp[i + max_size][j - 1]; 
            else if (i > 0)
              num_ones += -dp[i - 1][j + max_size];
            if (num_ones <= query) break;
          }
          if (global_max_size < max_size + 1) global_max_size = max_size + 1; 
        }
      }
      // free dp memory here
      return global_max_size;
    }
    
    int main() {
      #define N 8
      #define M 8
      int **matrix = malloc(sizeof(int*) * N);
      for (int i = 0; i < N; ++i) matrix[i] = malloc(sizeof(int) * M);
      for (int i = 0; i < N; ++i) 
        for (int j = 0; j < M; ++j)
          matrix[i][j] = 0;
    
      matrix[0][0] = matrix[1][1] = 1;
    
      printf("%d\n", max_square_submatrix(matrix, 8, 8, 1));
      printf("%d\n", max_square_submatrix(matrix, 8, 8, 2));
      printf("%d\n", max_square_submatrix(matrix, 8, 8, 0));
      printf("%d\n", max_square_submatrix(matrix, 8, 8, 1001));
    }
    

    【讨论】:

    • 我看过这个链接,我无法适应。你能详细说明一下吗?
    • 我已经为您编写了解决方案,但它可能仍然有点难以理解。尝试查看代码以及链接的文章。
    猜你喜欢
    • 2013-07-21
    • 2018-02-22
    • 1970-01-01
    • 2021-12-11
    • 1970-01-01
    • 2013-07-18
    • 2014-03-13
    • 2019-09-27
    • 1970-01-01
    相关资源
    最近更新 更多