题目链接

矩阵区域和

题目描述

image.png

实现代码

前缀和的思想,首先记dp[i][j]表示从(0,0)位置到(i,j)位置组成的矩形区域和;状态转移方程为:

dp[i][j] = dp[i-1][j] + dp[i][j-1] + mat[i][j] - dp[i-1][j-1]

可由下图直观看出
image.png

然后,该题要求的结果记res[i][j],则将其画出来可以看到,res[i][j]可以通过dp[i][j]进行表示,如下图:
image.png

实现代码如下:

  1. public int[][] matrixBlockSum(int[][] mat, int k) {
  2. int m = mat.length,n = mat[0].length;
  3. int[][] dp = get_dp(mat,m,n);
  4. return get_res(dp,m,n,k);
  5. }
  6. //获取dp数组
  7. public int[][] get_dp(int[][] arr,int m,int n){
  8. int[][] dp = new int[m+1][n+1];
  9. for (int i = 0; i < m; i++)
  10. for (int j = 0; j < n; j++)
  11. dp[i+1][j+1] = dp[i][j+1]+dp[i+1][j]+arr[i][j]-dp[i][j];
  12. return dp;
  13. }
  14. //获取结果
  15. public int[][] get_res(int[][] dp,int m,int n,int k){
  16. int[][] res = new int[m][n];
  17. int x1,y1,x2,y2;
  18. for (int i = 0; i < m; i++) {
  19. for (int j = 0; j < n; j++) {
  20. x1 = Math.max(0,i-k);y1 = Math.max(0,j-k);
  21. x2 = Math.min(m,i+k+1);y2 = Math.min(n,j+k+1);
  22. res[i][j] = dp[x2][y2]-dp[x1][y2]-dp[x2][y1]+dp[x1][y1];
  23. }
  24. }
  25. return res;
  26. }