523. Continuous Subarray Sum

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:

  1. The length of the array won't exceed 10,000.
  2. 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;
	}
};



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值