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.
Note:
- The length of the array won't exceed 10,000.
- You may assume the sum of all the numbers is in the range of a signed 32-bit integer.
分析:
输入[ 23, 2, 6, 4, 7], 目标为k, 为例, 以数据结构Elem记录每趟循环子序列之和以及后一个子序列的最后一个元素(红色),
先将队列que初始化为长度为5, 每个子序列长度为1, Elem存储的子序列之和以及最后一个元素均为子序列本身,
初始队列内容为(23,
23), (2,
2), (6,
6), (4,
4), (7,
7),
在初始队列的基础上,取出que队首元素的子序列和subSum, que队首出队, 再取当前que队首的最后一个元素lastElem, 将subSum与lastElem之和、lastElem用数据结构Elem保存, 构建新的队列que1: (23+2,
2), (2+6,
6), (6+4,
4), (4+7,
7), 若que1中存在元素的子序列和对k求余的值为0, 返回true, 否则, 将que1赋值给que, 循环该步骤, 得到新的que1为:
(23+2+6,
6), (2+6+4,
4), (6+4+7,
7)若que1中存在元素的子序列和对k求余的值为0, 返回true, 否则, 将que1赋值给que, 继续循环操作;
若最后得到que1为长度为1, 即子序列之和为原序列之和, 若子序列之和对k求余结果为0, 则返回true, 若循环结束仍未找到对k求余为0的子序列之和, 返回false.
struct Elem{
int subSum;
int lastElem;
};
class Solution {
public:
bool checkSubarraySum(vector<int>& nums, int k) {
int len = nums.size();
queue<Elem> que;
queue<Elem> que1;
int subSum;
int lastElem;
int cnt = 1;
Elem elem;
if (k < 0) k = -k;
if (len < 2)return false;
for (vector<int>::iterator itr = nums.begin(); itr != nums.end(); itr++){
elem.subSum = *itr;
elem.lastElem = *itr;
que.push(elem);
}//que初始化
while (cnt != len){
while(que.size()!=1){
subSum = que.front().subSum;
que.pop();
lastElem = que.front().lastElem;
subSum = subSum + lastElem;
elem.subSum = subSum;
elem.lastElem = lastElem;
que1.push(elem);
if (k != 0){
if (subSum % k == 0) return true;
}
else {
if (subSum == 0) return true;
}
}//while
que.pop();
cnt++;
que = que1;
while (!que1.empty()){
que1.pop();
}
}//while
return false;
}
};