leetcode 1074:元素和为目标值的子矩阵数量

每日一题
今天的每日一题确实让博主我伤透脑筋 :x
闲话不多说~ 来人! 上图!
在这里插入图片描述
看完题目的我,也不准备重拳出击了,代码能过就好…

首先来分析题目
大致意思呢就是 ,他要让我们拿所有可能的子矩阵的sum值和target比较,通过计数来得出有多少子矩阵的sum值。

第一步
通过二维数组前缀和得把这个子矩阵的sum值拿到在这里插入图片描述我们把每个方块比作矩阵中的1个元素,那么这个矩阵的sum值可由 S(红色) + S(蓝色) - S(红蓝) + S(黄色对勾) 得到。这里的S就代表了子矩阵元素的sum值。
如果解释的还不够清楚,下面我附上官方解释…
在这里插入图片描述在这里插入图片描述

在这里插入图片描述第二步
通过切割得到任一子矩阵的sum值(子矩阵位置不定)
看了我的解释和官方的解释,肯定有人和我当初一样有疑惑:怎么把所有子矩阵的sum值都遍历一遍呢?
我只想到了暴力,毕竟一力降十会hhhh
对于不同位置的子矩阵,我们可以通过切割来计算它的sum值在这里插入图片描述
就比如我要求紫色对勾这个子矩阵的sum值(想象里面存在元素…)就可以类比上面的公式得出
S(4) - S(3) - S(2) + S(1) 这里S同样是矩阵元素的sum值。
下面附上代码块
比较暴力…毕竟一力降十会hhh

class Solution {
    public int numSubmatrixSumTarget(int[][] matrix, int target) {
        int[][] sums = new int[matrix.length+1][matrix[0].length+1];
        for(int i = 1; i < sums.length; ++i){
            for(int j = 1; j < sums[0].length; ++j){
                sums[i][j] = sums[i-1][j] + sums[i][j-1] - sums[i-1][j-1]+matrix[i-1][j-1];
            }
        }
        int res = 0;
        for(int i = 1; i < sums.length; ++i){
            for(int j = 1; j < sums[0].length; ++j){
                for(int k = 0; k < i; ++k){
                    for(int t = 0; t < j; ++t){
                        if((sums[i][j]-sums[k][j]-sums[i][t]+sums[k][t]) == target){
                            res++;
                        }
                    }
                }
            }
        }
        return res;
    }
}

要注意for循环里面的i,j限制条件…(卡在这了好久)

补充
第一步还可以用一维数组的前缀和进行计算,详细可见leetcode304
这里不多赘述。

官方正解
在这里插入图片描述

class Solution {
    public int numSubmatrixSumTarget(int[][] matrix, int target) {
        int ans = 0;
        int m = matrix.length, n = matrix[0].length;
        for (int i = 0; i < m; ++i) { // 枚举上边界
            int[] sum = new int[n];
            for (int j = i; j < m; ++j) { // 枚举下边界
                for (int c = 0; c < n; ++c) {
                    sum[c] += matrix[j][c]; // 更新每列的元素和
                }
                ans += subarraySum(sum, target);
            }
        }
        return ans;
    }

    public int subarraySum(int[] nums, int k) {
        Map<Integer, Integer> map = new HashMap<Integer, Integer>();
        map.put(0, 1);
        int count = 0, pre = 0;
        for (int x : nums) {
            pre += x;
            if (map.containsKey(pre - k)) {
                count += map.get(pre - k);
            }
            map.put(pre, map.getOrDefault(pre, 0) + 1);
        }
        return count;
    }
}


作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/number-of-submatrices-that-sum-to-target/solution/yuan-su-he-wei-mu-biao-zhi-de-zi-ju-zhen-8ym2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

确实没想到用哈希表来做…
水平还是不够…

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值