202 前缀和解为K的子数组

本文介绍了如何在给定整数数组中计算和为k的连续子数组数量,提供了暴力求解、递归方法和利用前缀和的优化解决方案。前缀和方法通过哈希映射显著减少了查找次数,提高了效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述:给定一个整数数组和一个整数k,你需要找到该数组中和为k的连续子数组的个数。

暴力求解:枚举数组nums中的所有子数组,然后统计子数组和等于k的个数。

public int foreSumK(int []nums)
{
int number=0;
for(int i=0;i<nums.length;i++)
{
int sum=0;
for(int j=i;j<nums.length;j++)
{
sum+=nums[j];
if(sum==k){number++;}
}
}
return number;
}

递归方法求解:每一个元素都有选或者不选两种状态。

int number=0;
public void dfs(int []nums,int level,int sum)
{
if(level>=nums.length){return;}
if(sum+nums[level]==k){number++;}
dfs(nums,level+1,sum+nums[level]);
dfs(nums,level+1,sum);
}

public int Dfs(int[]nums,int level)
{
dfs(nums,0,0);
return number;
}

前缀和求解:

定义pre[i]为前面所有0到i个元素的总和,要求i到j之间的元素和,直接使用pre[j]-pre[i-1]即可,只要两者相减等于k,则表示找到了一个子数组,由于k值是固定的,对于确定的pre[j],只要找打pre[i-1]即可,可以使用map进行保存。

public int foreSumK(int[]nums)
{
int pre[]=new int[nums.length];
pre[0]=nums[0];
for(int i=1;i<nums.length;i++)
{
pre[i]=nums[i]+pre[i-1];
}
Map<Integer,Integer>map=new HashMap<>();
for(int i=0;i<nums.length;i++)
{
map.put(nums[i],map.getOrDefault(nums[i],0)+1);
}
int number=0;
for(int i=0;i<nums.length;i++)
{
if(map.containsKey(pre[i]-k))
{
number+=map.get(pre[i]-k);
}
}
return number;
}

### 和为k的连续子数组问题 对于和为k的连续子数组问题,可以通过前缀和与哈希表相结合的方法高效解决。这种方法的核心思想在于利用前缀和的概念减少重复计算,并借助哈希表存储中间结果以加速查询过程。 #### 前缀和概念 前缀和是一种用于快速计算区间和的技术。定义 `prefix_sum[i]` 表示从数组起始位置到第i个元素之间的累计和,则任意子数组 `[j, i]` 的和可通过如下公式得到: \[ \text{subarray\_sum[j:i]} = \text{prefix_sum[i]} - \text{prefix_sum[j-1]} \] 如果存在某个索引 \( j \),使得 \( prefix\_sum[i] - prefix\_sum[j-1] = k \),那么我们找到了一个满足条件的子数组[^3]。 #### 使用哈希表优化查找 为了进一步提高效率,在遍历过程中维护一个哈希表记录已经遇到过的前缀和及其出现次数。当处理当前元素时,检查是否存在 \( prefix\_sum[i] - k \) 已经存在于哈希表中;如果有,则表示之前某些位置上的前缀和加上当前位置之后的部分正好构成目标值k的一个有效子数组组合[^5]。 以下是基于上述原理的具体Python实现: ```python def subarraySum(nums, k): count = 0 sums = 0 d = {0: 1} # 初始化字典,键为前缀和,值为其出现次数 for num in nums: sums += num if (sums - k) in d: count += d[sums - k] if sums not in d: d[sums] = 0 d[sums] += 1 return count ``` 此函数接收两个参数:一个是整数列表nums代表待分析的数据序列;另一个是整数值k作为期望达到的目标总和。它会返回符合条件的不同子数组数目[^4]。 ### 结论 通过采用前缀和配合哈希表的方式能够有效地降低时间复杂度至线性级别(O(n)),从而解决了传统暴力枚举方法所带来的性能瓶颈问题[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值