leetcode每日一题-560. 和为K的子数组

560. 和为K的子数组

给定一个整数数组和一个整数 k,你需要找到该数组中和为 k 的连续的子数组的个数。
举例

输入:nums = [1,1,1], k = 2
输出: 2 , [1,1][1,1] 为两种不同的情况。

思路(参考题解中@天使爆破组):
暴力解法:
枚举所有子数组,i为子数组开端,j为子数组结束,累计nums[i]+... +nums[j]=k?,代码如下:

int count =0;
for(int i = 0;i < nums.size();++i){
     
	for(int j = 0;j < nums.size();++j){
     
		int sum = 0;
		for(int m = i;m < j;++m){
     
			sum += nums[m];
		}
		if(sum == k) count++;
	}
}
return count;

可以发现,且第三层循环都是以i开始,且第j项的sum等于j-1项的sum加上j项的值,即sum[i] = sum[i-1] + nums[i];所以我们可以省去第三层循环。

int count =0;
for(int i = 0;i < nums.size();++i){
     
	int sum = 0;
	for(int j = 0;j < nums.size();++j){
     
		sum += nums[j];
		if(sum == k) count++;
	}
}
return count;

我们知道,从ij的和等于从0j的和减去从0i-1的和,例如1+2+3+4,(3+4)=(1+2+3+4)-(1+2),我们可以把每一项的和保存起来,计算sum[j]-sum[i-1]=k的个数,转化为符合sum[j]-k=sum[i-1]i的个数,,寻找某一值对应的个数,而且sum[j]=sum[j-1]+nums[j]可以使用Hashmap,其中,键为i,值为个数,map[0]=1代表初始状态,没有开始加和。代码如下:

unordered_map<int,int> map;
map[0]=1;
int count = 0;
int sum = 0;
for(auto s:nums){
     
	sum += s;
	if(map[sum-k]) count+=map[sum-k];
	map[sum]++;
}
return count;

**PS:**才疏学浅,供自己备忘使用,欢迎指正。

你可能感兴趣的:(leetcode刷题,学习)