Halo, this is Ppeua. Usually, I mainly update C++, data structure algorithm, Linux and ROS... If you are interested, follow me bua!
and is a subarray of K
topic:
Example:
answer:
Solution one:
Violent solution: We can easily think of the possibility of traversing all the sums in the array through two for loops, and then judge how many satisfy K. His code is very simple, so it is directly given here.
class Solution {
public:
int subarraySum(vector<int>& nums, int k) {
int count = 0;
for (int start = 0; start < nums.size(); ++start) {
int sum = 0;
for (int end = start; end >= 0; --end) {
sum += nums[end];
if (sum == k) {
count++;
}
}
}
return count;
}
};
Here, a start and end are used to control the interval of the sub-array. If it is K, it counts ++.
We carefully observe this approach. It can be easily found that **We can solve the problem of two-layer loops through the prefix sum. **So there is the second method of understanding: use the prefix sum to solve this kind of problem.
Solution two:
Uu who are not familiar with the prefix sum can read this article: [Prefix sum]( (138 messages) [High-precision addition, subtraction, multiplication and division, 1D and 2D prefix sum && difference] Idea explanation and code implementation_ppeua's blog -CSDN blog )
Here we start to deduce directly, here we use the one-dimensional prefix and method.
Definition: **pre[i]** represents the sum of all array elements from 0 to i.
Then according to the definition of the prefix sum: the sum of the elements in the interval j~i can be expressed as: pre[i]-pre[j-1] , what we need to judge is whether this result can be equal to K.
So the current solution is simplified to the following formula:
We can get by simple mathematical derivation on both sides of the formula.
In this way, we can store the value through a hash, and then just verify whether the prefix and -k result of the current traversal appear in the hash. If it appears, then + the number of times it appears.
The code is simpler:
class Solution {
public:
int subarraySum(vector<int>& nums, int k) {
for(int i=1;i<nums.size();i++)
{
nums[i]+=nums[i-1];
}
unordered_map<int,int>mp;
mp[0]=1;
int res=0;
for(int i=0;i<nums.size();i++)
{
if(mp.find(nums[i]-k)!=mp.end())
{
res+=mp[nums[i]-k];
}
mp[nums[i]]++;
}
return res;
}
};
There are two important questions:
-
Why mp[0]=1?
In order to deal with nums[0] +nums[1] + ... + nums[i] == k , that is, the accumulation from subscript 0 to subscript i is just satisfied.
For example: k is 6
In this case, when traversing to the position where the original array is 3 and the prefix and array are 6 for the first time. At this time, pre-k=0 is just enough to meet the situation. So you need to preset a mp[0 ]=1 case.
-
Why res+=mp[nums[i]-k]:
For example: K is still 6
The answer to this question is 4. When traversing to the first position of 6, the first answer is obtained. When traversing to the second position, the second answer is obtained. Both cases are: pre- k=0
When traversing to 12, the third answer is obtained, and at this time pre-k=6. So there are only three answers at this time? No, 12-the first 6 is an answer. 12-the second 6 is also an answer.
When traversing to the second position, get the second answer. In both cases: pre-k=0
When traversing to 12, the third answer is obtained, and at this time pre-k=6. So there are only three answers at this time? No, 12-the first 6 is an answer. 12-the second 6 is also an answer.
So: res+=mp[nums[i]-k] is to directly add the possibility of the same situation.