最直观的想法是遍历数组并依次加当前位置的数字.,同时用数组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; } };