随笔 - 384  文章 - 0  评论 - 0  阅读 - 13万

力扣560(java&python)-和为k的子数组(中等)

题目:

给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的连续子数组的个数 。

 示例 1:

输入:nums = [1,1,1], k = 2
输出:2
示例 2:

输入:nums = [1,2,3], k = 3
输出:2
 

提示:

1 <= nums.length <= 2 * 104
-1000 <= nums[i] <= 1000
-107 <= k <= 107

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/subarray-sum-equals-k
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路:

前缀和+哈希表:

前缀和:表示nums的第0项到当前项的和。

  • 定义一个prefixSum数组,prefixSum[x]:第0项到第x项的和。prefixSum[x] = nums[0] + nums[1]+...+nums[x];
  • nums的某项 = 两个相邻前缀和之差:nums[x] = prefixSum[x] - prefixSum[x - 1]
  • nums的第 i 到 j 项的和:nums[i]+...+nums[j] = prefixSum[j] - prefixSum[i-1]
  • 当 i 为0时,此时i-1 = -1,故意让prefixSum[-1]为0,使得通式在i=0时也成立:nums[0] + ...+ nums[j] = prefixSum[j]

题目的意思就是求从第i 到 j项的子数组和等于k <==>有几种ij组合,满足prefixSum[j] -prefixSum[i -1] == k。

  • 不关心具体那两项的前缀和之差为k,只关心前缀和之差为k出现的次数;
  • 在遍历nums之前,故意让-1所对应的前缀和为0,这样通式在边界情况也成立,即在遍历之前,首先将前缀和为0 出现1次了 ==><0 : 1>放入map中;
  • 遍历nums,求每一项的前缀和,统计对应的出现次数,以键值对存入map;
  • 边存边查看map,如果map中存在key为【当前前缀和 - k】,说明之前出现的前缀和满足【当前前缀和 - key == k】,它出现的次数不断累加给count。

java代码:

复制代码
 1 class Solution {
 2     public int subarraySum(int[] nums, int k) {
 3         Map<Integer, Integer> map = new HashMap<>();
 4         //先把边界<0, 1>:前缀和为0的次数加入到map中
 5         map.put(0,1);
 6         int presum = 0;
 7         int count = 0;
 8         //计算前缀和
 9         for(int num : nums){
10             presum += num;
11             //如果存在历史前缀和,则将次数统计到count中
12             if(map.containsKey(presum - k)){
13                 count += map.get(presum - k);
14             }
15             map.put(presum, map.getOrDefault(presum, 0) + 1);
16         }
17         return count;
18     }
19 }
复制代码

 python3代码:

复制代码
 1 class Solution:
 2     def subarraySum(self, nums: List[int], k: int) -> int:
 3         #当key不存在,默认为0
 4         map = collections.defaultdict(int)
 5         count = 0
 6         n = len(nums)
 7         presum = 0
 8         map[0] = 1
 9         for i in range(n):
10             presum += nums[i]
11 
12             count +=  map[presum - k]
13             map[presum] += 1
14         return count 
复制代码

posted on   我不想一直当菜鸟  阅读(30)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
历史上的今天:
2021-10-17 力扣414(java)-第三大的数(简单)
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示