题目链接:https://leetcode.com/problems/continuous-subarray-sum/#/description
Given a list of non-negative numbers and a target integer k, write a function to check if the array has a continuous subarray of size at least 2 that sums up to the multiple of k, that is, sums up to n*k where n is also an integer.
Example 1:
Input: [23, 2, 4, 6, 7], k=6
Output: True
Explanation: Because [2, 4] is a continuous subarray of size 2 and sums up to 6.
Example 2:
Input: [23, 2, 6, 4, 7], k=6
Output: True
Explanation: Because [23, 2, 6, 4, 7] is an continuous subarray of size 5 and sums up to 42.
思路:
如果要求和刚好为k的话,我们对于当前和si,只需要知道之前是否存在sj=si−k即可,于是可以用unordered_map
O(1)的去查找。
既然是k的整数倍,我们可以利用%的性质:
x%p=a等价于x=pn+a(1)
y%p=a等价于y=pm+a(2)
(2)和(1)相减既有:y−x=p(m−n),即y−x是p的整数倍。
所以,我们不维护前缀和而是前缀和%k之后的值x,并且用map保存每个x出现的最早位置,当再次出现x的时候,并且长度大于1,那么就是我们的结果。
class Solution{
public:
bool checkSubarraySum(vector<int>& nums,int k)
{
int n=nums.size(),sum=0,pre=0;
unordered_set<int> modk;
for(int i=0;i<n;i++)
{
sum+=nums[i];
int mod=k==0?sum:sum%k;
if(modk.count(mod)) return true;
modk.insert(pre); //第一次插入是0的原因,例子[3,3,4],k=6,3+3%6==0
pre=mod;
}
return false;
}
};