最直观的想法是遍历数组并依次加当前位置的数字.,同时用数组sum记录下当前位置之前所有数字的相加和。
class Solution {
public:
int subarraySum(vector<int>& nums, int k) {
//nums={1,2,1,2,1};
// k=3;
int len=nums.size();
if(len<=0) return 0;
if(len==1)
{
if(nums[0]==k) return 1;
else return 0;
}
int sum;
int count=0;
// sort(nums.begin(),nums.end());
for(int i=0;i<=len-1;i++)
{
sum=nums[i];
if(sum==k) count++;
for(int j=i+1;j<=len-1;j++)
{
sum+=nums[j];
if(sum==k) count++;
}
}
return count;
}
};
用sum表示从数组开始位置到当前位置的数字相加和
,
我们还可以用Hash Table来存储sum出现的次数,如果当前位置之前有相加和为sum-k的位置,则这两个位置之间的数字相加和为k,以当前位置结尾的相加和为k的子数组个数为hash[sum-k],这样遍历整个数组即可得出满足条件的子数组个数。具体代码:
class Solution {
public:
int subarraySum(vector<int>& nums, int k) {
//nums={1,2,1,2,1};
// k=3;
int len=nums.size();
if(len<=0) return 0;
if(len==1)
{
if(nums[0]==k) return 1;
else return 0;
}
int sum=0;
int count=0;
unordered_map<int,int> tmp;
tmp[0]=1;//为了满足当前数字就是K
for(int i=0;i<=len-1;i++)
{
sum+=nums[i];
count+=tmp[sum-k];
tmp[sum]++;
}
return count;
}
};
523
class Solution {//最简单的动态规划
public:
bool checkSubarraySum(vector<int>& nums, int k) {
// nums={0,0};
// k=0;
unordered_map<int, int> hash;
int sum = 0;
hash[0] = 0;//代码中hash[0] = -1这行即为了便于边界情况的处理
for(int i=0; i<nums.size(); ++i) {
sum += nums[i];
if(k) sum %= k;
if(hash.find(sum) != hash.end()) {
if(i-hash[sum] > 1) return true;//记录的是最开始的那个余数的index,为了使得长度大于等于2
}
else hash[sum] = i;
}
return false;
}
};
暴力方法:
class Solution {
public:
bool checkSubarraySum(vector<int>& nums, int k) {
int len=nums.size();
if(len<=1) return false;
int sum;
for(int i=0;i<=len-1;i++)
{
sum=nums[i];
for(int j=i+1;j<=len-1;j++)
{
sum+=nums[j];
if(k==sum||(k!=0&&sum%k==0))
return true;
}
}
return false;
}
};