(算法)矩阵区域和————<前缀和数组>

1. 题⽬链接:1314.矩阵区域和 

2. 题⽬描述:

3. 解法:

算法思路:

⼆维前缀和的简单应⽤题,关键就是我们在填写结果矩阵的时候,要找到原矩阵对应区域的「左上 ⻆」以及「右下⻆」的坐标(推荐⼤家画图)

左上⻆坐标: x1 = i - k,y1 = j - k ,但是由于会「超过矩阵」的范围,因此需要对0 取⼀个max 。因此修正后的坐标为: x1 = max(0, i - k), y1 = max(0, j - k) ;

 右下⻆坐标: x1 = i + k,y1 = j + k ,但是由于会「超过矩阵」的范围,因此需要对m - 1 ,以及n - 1 取⼀个min 。因此修正后的坐标为: x2 = min(m - 1, i + k), y2 = min(n - 1, j + k) 。 

然后将求出来的坐标代⼊到「⼆维前缀和矩阵」的计算公式上即可~(但是要注意下标的映射关 系)

C++算法代码: 

class Solution 
{
public:
    vector<vector<int>> matrixBlockSum(vector<vector<int>>& mat, int k) 
    {
        int m=mat.size(),n=mat[0].size();
        //为了避免越界,行列都多开一行(列)
        //二维前缀和表
        vector<vector<int>>qzh(m+1,vector<int>(n+1));
        for(int i=1;i<m+1;i++)
        {
            for(int j=1;j<n+1;j++)
            {
                //此题数据的下标从1开始,故mat数据坐标要-1
                qzh[i][j]=qzh[i-1][j]+qzh[i][j-1]-qzh[i-1][j-1]+mat[i-1][j-1];
            }
        }
        //答案数组
        vector<vector<int>>answer(m,vector<int>(n));
        for(int i=0;i<m;i++)
        {
            for(int j=0;j<n;j++)
            {
                //防止越界访问,越界点则定在边界上
                //为了坐标与前缀和数组小标==下标对应,所以都要+1
                int x1=max(0,i-k)+1,y1=max(0,j-k)+1;
                int x2=min(m-1,i+k)+1,y2=min(n-1,j+k)+1;
                answer[i][j]=qzh[x2][y2]-qzh[x2][y1-1]-qzh[x1-1][y2]+qzh[x1-1][y1-1];
            }
        }
        return answer;
    }
};

 Java算法代码:

class Solution {
	public int[][] matrixBlockSum(int[][] mat, int k) {
		int m = mat.length, n = mat[0].length;
		// 1. 预处理前缀和矩阵 
		int[][] dp = new int[m + 1][n + 1];
		for (int i = 1; i <= m; i++)
			for (int j = 1; j <= n; j++)
				dp[i][j] = dp[i - 1][j] + dp[i][j - 1] - dp[i - 1][j - 1] +
				mat[i - 1][j - 1];

		// 2. 使⽤ 
		int[][] ret = new int[m][n];
		for (int i = 0; i < m; i++)
			for (int j = 0; j < n; j++)
			{
				int x1 = Math.max(0, i - k) + 1, y1 = Math.max(0, j - k) + 1;
				int x2 = Math.min(m - 1, i + k) + 1, y2 = Math.min(n - 1, j +
					k) + 1;
				ret[i][j] = dp[x2][y2] - dp[x1 - 1][y2] - dp[x2][y1 - 1] +
					dp[x1 - 1][y1 - 1];
			}
		return ret;
	}
}
  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

课堂随笔

感谢支持~~~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值