📜  生成一个矩阵,其每个元素都等于给定矩阵的指定子矩阵的总和

📅  最后修改于: 2021-09-06 05:07:08             🧑  作者: Mango

给定维度为M*N的矩阵mat[][]和整数K ,任务是生成矩阵answer[][] ,其中answer[i][j]等于所有元素mat[r的总和]这样 r ∈ [i – K, i + K], c ∈ [j – K, j + K](r, c)是矩阵中的有效位置。

例子:

朴素的方法:最简单的方法是使用两个嵌套循环遍历矩阵元素并计算所有元素的总和mat[r] ( i – K ≤ r ≤ i + K, j – K ≤ c ≤ j+K ) ,对于每个可能的答案[i][j] 。最后,遍历矩阵后打印矩阵。

时间复杂度: O(N 4 )  
辅助空间: O(1)

基于前缀和的方法:为了优化上述方法,其思想是初始化一个辅助矩阵aux[M][N]来存储矩阵mat[][]的所有行的前缀和。一旦构建了aux[][] ,就可以通过遍历[i – K ≤ r ≤ i + K]范围内的所有行并添加aux[r][max_col] – aux[r ]来计算answer[i][j] ][min_col] + aux[r][min_col]到它。添加的这个值表示row[r]answer[i][j]贡献的总和。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function to find the required matrix
void matrixBlockSum(vector> mat,int K)
{
 
    // Stores number of rows and columns
    int n = mat.size();
    int m = mat[0].size();
    vector> mat1(n, vector(m));
 
    // Traverse the matrix mat[][]
    // row-wise to calculate prefix row sum
    int cnt = 1;
    for (int i = 0; i < n; i++)
    {
        int k = 0;
        for (int j = 0; j < m; j++)
        {
 
            // Calculate Prefix Sum
            k += mat[i][j];
            mat1[i][j] = k;
            mat[i][j] = cnt;
            cnt += 1;
          }
      }
 
    // Declare the final matrix
    vector> ans;
 
    // Traverse the matrix row-wise
    // and fill valid indices ans[i][j]
    for (int i = 0; i < n; i++)
    {
 
        // Stores required sum of block
        // for each cell in current row
        vector temp;
        for (int j = 0; j < m; j++)
        {
 
            // Fix the bounds
            // i-k >=0 and i+k < n
            // j-k > =0 and j+k < m
            int mnr = max(0, i - K);
            int mnc = max(0, j - K);
            int mxr = min(n - 1, i + K);
            int mxc = min(m - 1, j + K);
            int ans1 = 0;
 
            // Iterate in range [minimum row(mnr),
            // maximum row(mxr)] and store the sum of row k
            for (int k = mnr; k <= mxr; k++)
                ans1 += (mat1[k][mxc] - mat1[k][mnc]) + mat[k][mnc];
 
            // Append it to temp
            temp.push_back(ans1);
          }
 
        // Append temp to final matrix
        ans.push_back(temp);
      }
 
    // Print the matrix
    int xx = ans.size(), y = 0;
    cout << "[";
    for(auto i:ans)
    {
      cout << "[";
      y++;
      int x = i.size();
      for(int j = 0; j < x - 1; j++)
        cout << i[j] << ", ";
      cout << i[x - 1] << "]";
      if(y < xx) cout << ", ";
    }
    cout << "] ";
}
 
// Driver Code
int main()
{
  vector> mat = { {1, 2, 3},
                             {4, 5, 6},
                             {7, 8, 9}};
  int K = 1;
  matrixBlockSum(mat, K);
  return 0;
}
 
// This code is contributed by mohit kumar 29.


Java
// Java program for the above approach
import java.io.*;
import java.util.*;
class GFG
{
 
  // Function to find the required matrix
  static void matrixBlockSum(int mat[][], int K)
  {
 
    // Stores number of rows and columns
    int n = mat.length;
    int m = mat[0].length;
    int mat1[][] = new int[n][m];
 
    // Traverse the matrix mat[][]
    // row-wise to calculate prefix row sum
    int cnt = 1;
    for (int i = 0; i < n; i++)
    {
      int k = 0;
      for (int j = 0; j < m; j++)
      {
 
        // Calculate Prefix Sum
        k += mat[i][j];
        mat1[i][j] = k;
        mat[i][j] = cnt;
        cnt += 1;
      }
    }
 
    // Declare the final matrix
    int ans[][] = new int[n][m];
 
    // Traverse the matrix row-wise
    // and fill valid indices ans[i][j]
    for (int i = 0; i < n; i++)
    {
 
      // Stores required sum of block
      // for each cell in current row
      // int temp = new int[m];
      for (int j = 0; j < m; j++)
      {
 
        // Fix the bounds
        // i-k >=0 and i+k < n
        // j-k > =0 and j+k < m
        int mnr = Math.max(0, i - K);
        int mnc = Math.max(0, j - K);
        int mxr = Math.min(n - 1, i + K);
        int mxc = Math.min(m - 1, j + K);
        int ans1 = 0;
 
        // Iterate in range [minimum row(mnr),
        // maximum row(mxr)] and store the sum of
        // row k
        for (int k = mnr; k <= mxr; k++)
          ans1 += (mat1[k][mxc] - mat1[k][mnc])
          + mat[k][mnc];
 
        // Append temp to final matrix
        ans[i][j] = (ans1);
      }
    }
 
    // Print the matrix
    int xx = ans.length, y = 0;
    System.out.print("[");
    for (int i = 0; i < n; i++)
    {
      System.out.print("[");
      y++;
      for (int j = 0; j < m - 1; j++)
        System.out.print(ans[i][j] + ", ");
      System.out.print(ans[i][m - 1] + "]");
      if (y < xx)
        System.out.print(", ");
    }
    System.out.print("] ");
  }
 
  // Driver Code
  public static void main(String[] args)
  {
    int mat[][]
      = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
    int K = 1;
    matrixBlockSum(mat, K);
  }
}
 
// This code is contributed by Dharanendra L V.


Python3
# Python3 program for the above approach
 
# Function to find the required matrix
 
 
def matrixBlockSum(mat, K):
 
    # Stores number of rows and columns
    n = len(mat)
    m = len(mat[0])
 
    # Traverse the matrix mat[][]
    # row-wise to calculate prefix row sum
    for i in range(n):
        k = 0
        for j in range(m):
 
            # Calculate Prefix Sum
            k += mat[i][j]
            mat[i][j] = (mat[i][j], k)
 
    # Declare the final matrix
    ans = []
 
    # Traverse the matrix row-wise
    # and fill valid indices ans[i][j]
    for i in range(n):
 
        # Stores required sum of block
        # for each cell in current row
        temp = []
        for j in range(m):
 
            # Fix the bounds
            # i-k >=0 and i+k < n
            # j-k > =0 and j+k < m
            mnr = max(0, i - K)
            mnc = max(0, j - K)
            mxr = min(n - 1, i + K)
            mxc = min(m - 1, j + K)
            ans1 = 0
 
            # Iterate in range [minimum row(mnr),
            # maximum row(mxr)] and store the sum of row k
            #print(mnr,mxr+1)
            for k in range(mnr, mxr+1):
                ans1 += (mat[k][mxc][1]-mat[k][mnc][1])+mat[k][mnc][0]
 
            # Append it to temp
            temp.append(ans1)
 
        # Append temp to final matrix
        ans.append(temp)
 
    # Print the matrix
    print(ans)
 
 
# Driver Code
if __name__ == "__main__":
 
    mat = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
    K = 1
    matrixBlockSum(mat, K)


C#
// C# program for the above approach
using System;
public class GFG
{
 
  // Function to find the required matrix
  static void matrixBlockSum(int [,]mat, int K)
  {
 
    // Stores number of rows and columns
    int n = mat.GetLength(0);
    int m = mat.GetLength(1);
    int [,]mat1 = new int[n,m];
 
    // Traverse the matrix [,]mat
    // row-wise to calculate prefix row sum
    int cnt = 1;
    for (int i = 0; i < n; i++)
    {
      int k = 0;
      for (int j = 0; j < m; j++)
      {
 
        // Calculate Prefix Sum
        k += mat[i,j];
        mat1[i,j] = k;
        mat[i,j] = cnt;
        cnt += 1;
      }
    }
 
    // Declare the readonly matrix
    int [,]ans = new int[n,m];
 
    // Traverse the matrix row-wise
    // and fill valid indices ans[i,j]
    for (int i = 0; i < n; i++)
    {
 
      // Stores required sum of block
      // for each cell in current row
      // int temp = new int[m];
      for (int j = 0; j < m; j++)
      {
 
        // Fix the bounds
        // i-k >=0 and i+k < n
        // j-k > =0 and j+k < m
        int mnr = Math.Max(0, i - K);
        int mnc = Math.Max(0, j - K);
        int mxr = Math.Min(n - 1, i + K);
        int mxc = Math.Min(m - 1, j + K);
        int ans1 = 0;
 
        // Iterate in range [minimum row(mnr),
        // maximum row(mxr)] and store the sum of
        // row k
        for (int k = mnr; k <= mxr; k++)
          ans1 += (mat1[k, mxc] - mat1[k, mnc])
          + mat[k, mnc];
 
        // Append temp to readonly matrix
        ans[i, j] = (ans1);
      }
    }
 
    // Print the matrix
    int xx = ans.Length, y = 0;
    Console.Write("[");
    for (int i = 0; i < n; i++)
    {
      Console.Write("[");
      y++;
      for (int j = 0; j < m - 1; j++)
        Console.Write(ans[i, j] + ", ");
      Console.Write(ans[i, m - 1] + "]");
      if (y < xx)
        Console.Write(", ");
    }
    Console.Write("] ");
  }
 
  // Driver Code
  public static void Main(String[] args)
  {
    int [,]mat
      = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
    int K = 1;
    matrixBlockSum(mat, K);
  }
}
 
// This code is contributed by 29AjayKumar


C++
// C++ program for the above approach
#include 
using namespace std;
 
const int M = 3;
const int N = 3;
 
// Function to generate the required matrix
void matrixBlockSum(int mat[][M], int K)
{
     
    // Stores count of rows and columns
    int n = N;
    int m = M;
     
    // Traverse the matrix to
    // to compute prefix sum
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < m; j++)
        {
            if (i - 1 >= 0)
            {
                mat[i][j] += mat[i - 1][j];
            }
            if (j - 1 >= 0)
            {
                mat[i][j] += mat[i][j - 1];
            }
            if (i - 1 >= 0 && j - 1 >= 0)
            {
                mat[i][j] -= mat[i - 1][j - 1];
            }
        }
    }
     
    int ans[n][m];
     
    // Traverse the matrix row-wise
    // to fill the required matrix
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < m; j++)
        {
         
            // Fix the boundaries
            // i-k >=0 and i+k < n
            // j-k > =0 and j+k < m
            int mnr = max(0, i - K);
            int mxr = min(i + K, n - 1);
            int mnc = max(0, j - K);
            int mxc = min(j + K, m - 1);
             
            // Add sum of elements between
            // (0, 0) and (mxr, mxc)
            ans[i][j] = mat[mxr][mxc];
             
            // Remove elements between
            // (0, 0) and (mnr-1, mxc)
            if (mnr - 1 >= 0)
            {
                ans[i][j] -= mat[mnr - 1][mxc];
            }
             
            // Remove elements between
            // (0, 0) and (mxr, mnc-1)
            if (mnc - 1 >= 0)
            {
                ans[i][j] -= mat[mxr][mnc - 1];
            }
             
            // Add aux[mnr-1][mnc-1] as
            // elements between (0, 0)
            // and (mnr-1, mnc-1) are
            // subtracted twice
            if (mnr - 1 >= 0 && mnc - 1 >= 0)
            {
                ans[i][j] += mat[mnr - 1][mnc - 1];
            }
        }
    }
     
    // Print the matrix 
    for(int i = 0; i < n; i++)
    {       
        for(int j = 0; j < m; j++)
        {
            cout << ans[i][j] << " ";
        }
    }
}
 
// Driver code
int main()
{
    int mat[][M] = { { 1, 2, 3 },
                     { 4, 5, 6 },
                     { 7, 8, 9 } };
    int K = 1;
     
    matrixBlockSum(mat, K);
}
 
// This code is contributed by rag2127


Java
// Java program for the above approach
import java.io.*;
 
class GFG
{
 
  // Function to generate the required matrix
  static void matrixBlockSum(int[][] mat, int K)
  {
 
    // Stores count of rows and columns
    int n = mat.length;
    int m = mat[0].length;
 
    // Traverse the matrix to
    // to compute prefix sum
    for (int i = 0; i < n; i++)
    {
      for (int j = 0; j < m; j++)
      {
        if (i - 1 >= 0)
        {
          mat[i][j] += mat[i - 1][j];
        }
        if (j - 1 >= 0)
        {
          mat[i][j] += mat[i][j - 1];
        }
        if (i - 1 >= 0 && j - 1 >= 0)
        {
          mat[i][j] -= mat[i - 1][j - 1];
        }
      }
    }
 
    int[][] ans = new int[n][m];
 
    // Traverse the matrix row-wise
    // to fill the required matrix
    for (int i = 0; i < n; i++)
    {
      for (int j = 0; j < m; j++)
      {
 
        // Fix the boundaries
        // i-k >=0 and i+k < n
        // j-k > =0 and j+k < m
        int mnr = Math.max(0, i - K);
        int mxr = Math.min(i + K, n - 1);
        int mnc = Math.max(0, j - K);
        int mxc = Math.min(j + K, m - 1);
 
        // Add sum of elements between
        // (0, 0) and (mxr, mxc)
        ans[i][j] = mat[mxr][mxc];
 
        // Remove elements between
        // (0, 0) and (mnr-1, mxc)
        if (mnr - 1 >= 0)
        {
          ans[i][j] -= mat[mnr - 1][mxc];
        }
 
        // Remove elements between
        // (0, 0) and (mxr, mnc-1)
        if (mnc - 1 >= 0)
        {
          ans[i][j] -= mat[mxr][mnc - 1];
        }
 
        // Add aux[mnr-1][mnc-1] as
        // elements between (0, 0)
        // and (mnr-1, mnc-1) are
        // subtracted twice
        if (mnr - 1 >= 0 && mnc - 1 >= 0)
        {
          ans[i][j] += mat[mnr - 1][mnc - 1];
        }
      }
    }
 
    // Print the matrix 
    for (int i = 0; i < n; i++)
    {       
      for (int j = 0; j < m; j++)
      {
        System.out.print(ans[i][j] + " ");
      }
    }
  }
 
  // Driver code
  public static void main (String[] args)
  {
    int[][] mat = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
    int K = 1;
    matrixBlockSum(mat, K);
  }
}
 
// This code is contributed by avanitrachhadiya2155.


Python3
# Python3 program for the above approach
 
# Function to generate the required matrix
 
 
def matrixBlockSum(mat, K):
 
        # Stores count of rows and columns
    n = len(mat)
    m = len(mat[0])
 
    # Traverse the matrix to
    # to compute prefix sum
    for i in range(n):
 
        for j in range(m):
 
            if i-1 >= 0:
                mat[i][j] += mat[i-1][j]
            if j-1 >= 0:
                mat[i][j] += mat[i][j-1]
            if i-1 >= 0 and j-1 >= 0:
                mat[i][j] -= mat[i-1][j-1]
 
    ans = [[0 for i in range(m)]for i in range(n)]
 
    # Traverse the matrix row-wise
    # to fill the required matrix
    for i in range(n):
        for j in range(m):
 
            # Fix the boundaries
            # i-k >=0 and i+k < n
            # j-k > =0 and j+k < m
            mnr = max(0, i - K)
            mxr = min(i + K, n-1)
            mnc = max(0, j - K)
            mxc = min(j + K, m-1)
 
            # Add sum of elements between
            # (0, 0) and (mxr, mxc)
            ans[i][j] = mat[mxr][mxc]
 
            # Remove elements between
            # (0, 0) and (mnr-1, mxc)
            if mnr - 1 >= 0:
                ans[i][j] -= mat[mnr-1][mxc]
 
            # Remove elements between
            # (0, 0) and (mxr, mnc-1)
            if mnc - 1 >= 0:
                ans[i][j] -= mat[mxr][mnc-1]
 
            # Add aux[mnr-1][mnc-1] as
            # elements between (0, 0)
                # and (mnr-1, mnc-1) are
            # subtracted twice
            if mnr - 1 >= 0 and mnc - 1 >= 0:
                ans[i][j] += mat[mnr - 1][mnc - 1]
 
    # Print the matrix
    print(ans)
 
 
# Driver Code
if __name__ == "__main__":
 
    mat = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
 
    K = 1
 
    matrixBlockSum(mat, K)


C#
// C# program for the above approach
using System;
class GFG
{
 
  // Function to generate the required matrix
  static void matrixBlockSum(int[, ] mat, int K)
  {
 
    // Stores count of rows and columns
    int n = mat.GetLength(0);
    int m = mat.GetLength(1);
 
    // Traverse the matrix to
    // to compute prefix sum
    for (int i = 0; i < n; i++)
    {
 
      for (int j = 0; j < m; j++)
      {
 
        if (i - 1 >= 0)
          mat[i, j] += mat[i - 1, j];
        if (j - 1 >= 0)
          mat[i, j] += mat[i, j - 1];
        if (i - 1 >= 0 && j - 1 >= 0)
          mat[i, j] -= mat[i - 1, j - 1];
      }
    }
 
    int[, ] ans = new int[n, m];
 
    // Traverse the matrix row-wise
    // to fill the required matrix
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
 
        // Fix the boundaries
        // i-k >=0 and i+k < n
        // j-k > =0 and j+k < m
        int mnr = Math.Max(0, i - K);
        int mxr = Math.Min(i + K, n - 1);
        int mnc = Math.Max(0, j - K);
        int mxc = Math.Min(j + K, m - 1);
 
        // Add sum of elements between
        // (0, 0) and (mxr, mxc)
        ans[i, j] = mat[mxr, mxc];
 
        // Remove elements between
        // (0, 0) and (mnr-1, mxc)
        if (mnr - 1 >= 0)
          ans[i, j] -= mat[mnr - 1, mxc];
 
        // Remove elements between
        // (0, 0) and (mxr, mnc-1)
        if (mnc - 1 >= 0)
          ans[i, j] -= mat[mxr, mnc - 1];
 
        // Add aux[mnr-1][mnc-1] as
        // elements between (0, 0)
        // and (mnr-1, mnc-1) are
        // subtracted twice
        if (mnr - 1 >= 0 && mnc - 1 >= 0)
          ans[i, j] += mat[mnr - 1, mnc - 1];
      }
    }
 
    // Print the matrix
    for (int i = 0; i < n; i++)
      for (int j = 0; j < m; j++)
        Console.Write(ans[i, j] + " ");
  }
 
  // Driver Code
  public static void Main()
  {
 
    int[, ] mat
      = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
    int K = 1;
    matrixBlockSum(mat, K);
  }
}
 
// This code is contributed by chitranayal.


输出:
[[12, 21, 16], [27, 45, 33], [24, 39, 28]]

时间复杂度: O(N 3 )
辅助空间: O(N 2 )

高效方法:优化上述方法,思路是初始化一个辅助矩阵aux[M][N] ,使得aux[i][j]子矩阵mat[0][0]中元素总和存储mat [i][j]使用以下表达式:

按照以下步骤构建辅助矩阵:

  • mat[][] 的第一行复制到aux[][]
  • 查找矩阵的列式总和并存储它。
  • 找到更新矩阵aux[][]行式总和。
  • 经过以上步骤,打印生成的矩阵aux[][]

下面是上述方法的实现:

C++

// C++ program for the above approach
#include 
using namespace std;
 
const int M = 3;
const int N = 3;
 
// Function to generate the required matrix
void matrixBlockSum(int mat[][M], int K)
{
     
    // Stores count of rows and columns
    int n = N;
    int m = M;
     
    // Traverse the matrix to
    // to compute prefix sum
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < m; j++)
        {
            if (i - 1 >= 0)
            {
                mat[i][j] += mat[i - 1][j];
            }
            if (j - 1 >= 0)
            {
                mat[i][j] += mat[i][j - 1];
            }
            if (i - 1 >= 0 && j - 1 >= 0)
            {
                mat[i][j] -= mat[i - 1][j - 1];
            }
        }
    }
     
    int ans[n][m];
     
    // Traverse the matrix row-wise
    // to fill the required matrix
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < m; j++)
        {
         
            // Fix the boundaries
            // i-k >=0 and i+k < n
            // j-k > =0 and j+k < m
            int mnr = max(0, i - K);
            int mxr = min(i + K, n - 1);
            int mnc = max(0, j - K);
            int mxc = min(j + K, m - 1);
             
            // Add sum of elements between
            // (0, 0) and (mxr, mxc)
            ans[i][j] = mat[mxr][mxc];
             
            // Remove elements between
            // (0, 0) and (mnr-1, mxc)
            if (mnr - 1 >= 0)
            {
                ans[i][j] -= mat[mnr - 1][mxc];
            }
             
            // Remove elements between
            // (0, 0) and (mxr, mnc-1)
            if (mnc - 1 >= 0)
            {
                ans[i][j] -= mat[mxr][mnc - 1];
            }
             
            // Add aux[mnr-1][mnc-1] as
            // elements between (0, 0)
            // and (mnr-1, mnc-1) are
            // subtracted twice
            if (mnr - 1 >= 0 && mnc - 1 >= 0)
            {
                ans[i][j] += mat[mnr - 1][mnc - 1];
            }
        }
    }
     
    // Print the matrix 
    for(int i = 0; i < n; i++)
    {       
        for(int j = 0; j < m; j++)
        {
            cout << ans[i][j] << " ";
        }
    }
}
 
// Driver code
int main()
{
    int mat[][M] = { { 1, 2, 3 },
                     { 4, 5, 6 },
                     { 7, 8, 9 } };
    int K = 1;
     
    matrixBlockSum(mat, K);
}
 
// This code is contributed by rag2127

Java

// Java program for the above approach
import java.io.*;
 
class GFG
{
 
  // Function to generate the required matrix
  static void matrixBlockSum(int[][] mat, int K)
  {
 
    // Stores count of rows and columns
    int n = mat.length;
    int m = mat[0].length;
 
    // Traverse the matrix to
    // to compute prefix sum
    for (int i = 0; i < n; i++)
    {
      for (int j = 0; j < m; j++)
      {
        if (i - 1 >= 0)
        {
          mat[i][j] += mat[i - 1][j];
        }
        if (j - 1 >= 0)
        {
          mat[i][j] += mat[i][j - 1];
        }
        if (i - 1 >= 0 && j - 1 >= 0)
        {
          mat[i][j] -= mat[i - 1][j - 1];
        }
      }
    }
 
    int[][] ans = new int[n][m];
 
    // Traverse the matrix row-wise
    // to fill the required matrix
    for (int i = 0; i < n; i++)
    {
      for (int j = 0; j < m; j++)
      {
 
        // Fix the boundaries
        // i-k >=0 and i+k < n
        // j-k > =0 and j+k < m
        int mnr = Math.max(0, i - K);
        int mxr = Math.min(i + K, n - 1);
        int mnc = Math.max(0, j - K);
        int mxc = Math.min(j + K, m - 1);
 
        // Add sum of elements between
        // (0, 0) and (mxr, mxc)
        ans[i][j] = mat[mxr][mxc];
 
        // Remove elements between
        // (0, 0) and (mnr-1, mxc)
        if (mnr - 1 >= 0)
        {
          ans[i][j] -= mat[mnr - 1][mxc];
        }
 
        // Remove elements between
        // (0, 0) and (mxr, mnc-1)
        if (mnc - 1 >= 0)
        {
          ans[i][j] -= mat[mxr][mnc - 1];
        }
 
        // Add aux[mnr-1][mnc-1] as
        // elements between (0, 0)
        // and (mnr-1, mnc-1) are
        // subtracted twice
        if (mnr - 1 >= 0 && mnc - 1 >= 0)
        {
          ans[i][j] += mat[mnr - 1][mnc - 1];
        }
      }
    }
 
    // Print the matrix 
    for (int i = 0; i < n; i++)
    {       
      for (int j = 0; j < m; j++)
      {
        System.out.print(ans[i][j] + " ");
      }
    }
  }
 
  // Driver code
  public static void main (String[] args)
  {
    int[][] mat = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
    int K = 1;
    matrixBlockSum(mat, K);
  }
}
 
// This code is contributed by avanitrachhadiya2155.

蟒蛇3

# Python3 program for the above approach
 
# Function to generate the required matrix
 
 
def matrixBlockSum(mat, K):
 
        # Stores count of rows and columns
    n = len(mat)
    m = len(mat[0])
 
    # Traverse the matrix to
    # to compute prefix sum
    for i in range(n):
 
        for j in range(m):
 
            if i-1 >= 0:
                mat[i][j] += mat[i-1][j]
            if j-1 >= 0:
                mat[i][j] += mat[i][j-1]
            if i-1 >= 0 and j-1 >= 0:
                mat[i][j] -= mat[i-1][j-1]
 
    ans = [[0 for i in range(m)]for i in range(n)]
 
    # Traverse the matrix row-wise
    # to fill the required matrix
    for i in range(n):
        for j in range(m):
 
            # Fix the boundaries
            # i-k >=0 and i+k < n
            # j-k > =0 and j+k < m
            mnr = max(0, i - K)
            mxr = min(i + K, n-1)
            mnc = max(0, j - K)
            mxc = min(j + K, m-1)
 
            # Add sum of elements between
            # (0, 0) and (mxr, mxc)
            ans[i][j] = mat[mxr][mxc]
 
            # Remove elements between
            # (0, 0) and (mnr-1, mxc)
            if mnr - 1 >= 0:
                ans[i][j] -= mat[mnr-1][mxc]
 
            # Remove elements between
            # (0, 0) and (mxr, mnc-1)
            if mnc - 1 >= 0:
                ans[i][j] -= mat[mxr][mnc-1]
 
            # Add aux[mnr-1][mnc-1] as
            # elements between (0, 0)
                # and (mnr-1, mnc-1) are
            # subtracted twice
            if mnr - 1 >= 0 and mnc - 1 >= 0:
                ans[i][j] += mat[mnr - 1][mnc - 1]
 
    # Print the matrix
    print(ans)
 
 
# Driver Code
if __name__ == "__main__":
 
    mat = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
 
    K = 1
 
    matrixBlockSum(mat, K)

C#

// C# program for the above approach
using System;
class GFG
{
 
  // Function to generate the required matrix
  static void matrixBlockSum(int[, ] mat, int K)
  {
 
    // Stores count of rows and columns
    int n = mat.GetLength(0);
    int m = mat.GetLength(1);
 
    // Traverse the matrix to
    // to compute prefix sum
    for (int i = 0; i < n; i++)
    {
 
      for (int j = 0; j < m; j++)
      {
 
        if (i - 1 >= 0)
          mat[i, j] += mat[i - 1, j];
        if (j - 1 >= 0)
          mat[i, j] += mat[i, j - 1];
        if (i - 1 >= 0 && j - 1 >= 0)
          mat[i, j] -= mat[i - 1, j - 1];
      }
    }
 
    int[, ] ans = new int[n, m];
 
    // Traverse the matrix row-wise
    // to fill the required matrix
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
 
        // Fix the boundaries
        // i-k >=0 and i+k < n
        // j-k > =0 and j+k < m
        int mnr = Math.Max(0, i - K);
        int mxr = Math.Min(i + K, n - 1);
        int mnc = Math.Max(0, j - K);
        int mxc = Math.Min(j + K, m - 1);
 
        // Add sum of elements between
        // (0, 0) and (mxr, mxc)
        ans[i, j] = mat[mxr, mxc];
 
        // Remove elements between
        // (0, 0) and (mnr-1, mxc)
        if (mnr - 1 >= 0)
          ans[i, j] -= mat[mnr - 1, mxc];
 
        // Remove elements between
        // (0, 0) and (mxr, mnc-1)
        if (mnc - 1 >= 0)
          ans[i, j] -= mat[mxr, mnc - 1];
 
        // Add aux[mnr-1][mnc-1] as
        // elements between (0, 0)
        // and (mnr-1, mnc-1) are
        // subtracted twice
        if (mnr - 1 >= 0 && mnc - 1 >= 0)
          ans[i, j] += mat[mnr - 1, mnc - 1];
      }
    }
 
    // Print the matrix
    for (int i = 0; i < n; i++)
      for (int j = 0; j < m; j++)
        Console.Write(ans[i, j] + " ");
  }
 
  // Driver Code
  public static void Main()
  {
 
    int[, ] mat
      = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
    int K = 1;
    matrixBlockSum(mat, K);
  }
}
 
// This code is contributed by chitranayal.
输出:
[[12, 21, 16], [27, 45, 33], [24, 39, 28]]

时间复杂度: O(N 2 )
辅助空间: O(N 2 )

如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live