Link to the problem
The problem is here: https://leetcode-cn.com/problems/number-of-submatrices-that-sum-to-target/
Background
Let us consider the problem lc-560. Subarray Sum equals K because we need to use some similar idea used in this problem.
lc-560. Subarray Sum equals K
For convenience, the problem description is copied here.
Given an array of integers nums and an integer k, return the total number of continuous subarrays whose sum equals to k.
Example 1:
- Input: nums = [1,1,1], k = 2
- Output: 2
Example 2:
- Input: nums = [1,2,3], k = 3
- Output: 2
Constraints:
- <= nums.length <= 2 * 104
- -1000 <= nums[i] <= 1000
- -107 <= k <= 107
Idea
We define . For simplicity, we also define . We are actually finding the number of different pairs s.t.
(N _is the length of nums) and
, i.e. for some j, we are finding the number of distinct i_ s.t. .
My implementation is this:
int subarraySum(vector<int>& nums, int k) {unordered_map<int, int> mp;// sum[-1] = 0mp[0] = 1;int sum = 0;int res = 0;for (auto n : nums) {sum += n;int delta = sum - k;auto it = mp.find(delta);if (it != mp.end()) {res += it->second;}mp[sum]++;}return res;}
I used a unordered_map, which is actually a hash table to boost the search of the number of i.
Use subarraySum for lc-1074
We can enumerate x1 and x2. Then we calculate the (sub-)column sum of the values between x1 and x2 for each column and store them in an array csum. Now the problem actually becomes exactly lc-560: csum is nums and target is k.
My implementation is this:
int numSubmatrixSumTarget(vector<vector<int>>& matrix, int target) {int m = matrix.size();int n = matrix[0].size();int res = 0;for (int upper = 0; upper < m; upper++) { // mvector<int> csum(n, 0);for (int bottom = upper; bottom < m; bottom++) { // mfor (int i = 0; i < n; i++) {csum[i] += matrix[bottom][i];}res += subarraySum(csum, target); // n}}// O(m^2*n) = 10^6return res;}
It is quite easy with the help of subarraySum.
