力扣 1074. 元素和为目标值的子矩阵数量 哈希 枚举

https://leetcode-cn.com/problems/number-of-submatrices-that-sum-to-target/
在这里插入图片描述
思路:考虑枚举左右边界 l 、 r l、r lr,计算该区间内每一行元素的和,可以得到一个数组 s u m sum sum,如果可以找到两个位置 i 、 j i、j ij满足 ∑ k = i j s u m k = t a r g e t \sum_{k=i}^{j}sum_k=target k=ijsumk=target,那么就找到了一组可行解,其左上角坐标为 ( l , i ) (l,i) (l,i),右下角坐标为 ( r , j ) (r,j) (r,j)。但是如果还是暴力枚举 i 、 j i、j ij判断的话,算法复杂度是 O ( n 2 m 2 ) O(n^2m^2) O(n2m2),怎么降低复杂度呢?

现在来考虑子问题:在数组 s u m sum sum中找到和为 t a r g e t target target的子区间个数。首先考虑暴力做法,我们可以先处理出 s u m sum sum数组的前缀和数组,设其为 t o t a l total total,然后限定区间右边界 r r r,再枚举区间左边界 l l l,判断 t o t a l r − t o t a l l − 1 total_r-total_{l-1} totalrtotall1是否等于 t a r g e t target target。因为 t o t a l r 、 t a r g e t total_r、target totalrtarget其实都是固定不变的,因此实际上我们是在求解在 t o t a l total total数组的区间 [ 0 , r ] [0,r] [0,r]内等于 t o t a l r − t a r g e t total_r-target totalrtarget的元素个数。那么可以用哈希表来记录,省去枚举的操作,降低时间复杂度。

class Solution {
public:
    int numSubmatrixSumTarget(vector<vector<int>>& matrix, int target) {
        int m=matrix.size(),n=matrix[0].size(),ans=0;
        // 枚举左边界
        for(int l=0;l<n;l++)
        {
            vector<int> sum(m);
            // 枚举右边界
            for(int r=l;r<n;r++)
            {
                // 更新每一行的和
                for(int i=0;i<m;i++)
                    sum[i]+=matrix[i][r];
                ans+=cal(sum,target);
            }
        }
        return ans;
    }

    int cal(const vector<int>& sum,int target)
    {
        int m=sum.size(),total=0,ans=0;
        unordered_map<int,int> cnt;
        cnt[0]=1;
        for(int i=0;i<m;i++)
        {
            total+=sum[i];
            auto it=cnt.find(total-target);
            if(it!=cnt.end())
                ans+=it->second;
            ++cnt[total];
        }
        return ans;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值