题目描述:https://leetcode-cn.com/problems/continuous-subarray-sum/description/
给定一个包含非负数的数组和一个目标整数 k,编写一个函数来判断该数组是否含有连续的子数组,其大小至少为 2,总和为 k 的倍数,即总和为 n*k,其中 n 也是一个整数。
示例 1:
输入: [23,2,4,6,7], k = 6
输出: True
解释: [2,4] 是一个大小为 2 的子数组,并且和为 6。
示例 2:
输入: [23,2,6,4,7], k = 6
输出: True
解释: [23,2,6,4,7]是大小为 5 的子数组,并且和为 42。
说明:
- 数组的长度不会超过10,000。
- 你可以认为所有数字总和在 32 位有符号整数范围内。
关键是找到转移方程,让以前累计的有用。
另外注意的是不需要N行,边计算边验证,只需要2行即可。否则无法开数组。
class Solution {
public:
int D[2][10000];
bool checkSubarraySum(vector<int>& nums, int k) {
int N=nums.size();
int kk=N;
int ilevel=0;
if(N==0) return false;
//if(k==0) return false;
for(int i=0; i<N; i++)
{
D[0][i]=nums[i];
D[1][i]=nums[i];
}
kk--;
ilevel++;
while(kk>0)
{
for(int i=0; i<kk; i++)
{
D[1][i]=D[1][i]+D[0][i+ilevel];
if((k==0&&D[1][i]==0)||(k!=0&&D[1][i]%k==0)) return true;
}
//cout<<endl;
kk--;
ilevel++;
}
return false;
}
};
或者采用穷举法,通过预处理 复杂性(n^2)
class Solution {
public:
int sum[10010];
bool checkSubarraySum(vector<int>& nums, int k) {
int N=nums.size();
int kk=N;
int ilevel=0;
if(N==0) return false;
nums.push_back(0);
//if(k==0) return false;
int isum=0;
for(int i=N; i>-1; i--)
{
isum+=nums[i];
sum[i]=isum;
}
for(int i=0; i<=N; i++)
for(int j=0; j<i-1; j++)
{
//if(i-j<2) continue;
isum=sum[j]-sum[i];
if((k==0&&isum==0)||(k!=0&&isum%k==0)) return true;
}
return false;
}
};