【LeetCode】【前缀和】560. 和为K的子数组

【前缀和】560. 和为K的子数组

知识点:数组;前缀和

题目描述

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

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

解法一:暴力法

直接以每个元素为首开始;

class Solution { public int subarraySum(int[] nums, int k) { int sum = 0; int count = 0; for(int i = 0; i < nums.length; i++){ //依次以元素开始; for(int j = i; j < nums.length; i++){ sum += nums[j]; if(sum == k) count++; } sum = 0; //一次结束后归零; } return count; } }

时间复杂度:O(N^N);

解法二:前缀和

前缀和是很常见的一种解题思路,其含义就是高中学过的数列的前n项和;
image
所以如果我们要求哪个子序列和为k的话,就可以转化为求前缀和数组中哪两个的值相减等于k。这熟悉吗?对啊,这不就是两数之和那个题吗?还记得怎么做的吗?就是用哈希表存,key和value分别就是数值和其索引下标,为什么存索引下标,因为那个题让我们求的就是索引下标。那类比一下,这个题呢,这个题是让我们干嘛,是求有几项和,那我们的value就是对应的前n项和为某个值的有几个,这样减出来的子序列就有几个;

// 前缀和没有优化; class Solution { public int subarraySum(int[] nums, int k) { int count = 0; int[] premsum = new int[nums.length+1]; //比原数组长一位,第一位置为0;这样才能把nums[1]包括; for(int i = 0; i < nums.length; i++){ //构建前缀和数组; premsum[i+1] = premsum[i] + nums[i]; } for(int i = 0; i < premsum.length-1; i++){ for(int j = i+1; j < premsum.length; j++){ if(premsum[j] - premsum[i] == k) count++; } } return count; } }

时间复杂度:依然是O(N^N);

// 前缀和+哈希表; class Solution { public int subarraySum(int[] nums, int k) { Map<Integer,Integer> map = new HashMap<>(); map.put(0,1); int premsum = 0; int count = 0; for(int i = 0; i < nums.length; i++){ premsum += nums[i]; //前缀和; if(map.containsKey(premsum-k)) count += map.get(premsum-k); map.put(premsum, map.getOrDefault(premsum, 0)+1); //前缀和为不同值的有几次; } return count; } }
  • python
class Solution: def subarraySum(self, nums: List[int], k: int) -> int: hashtable = {} hashtable[0] = 1 sum = count = 0 for i, num in enumerate(nums): sum += num target = sum-k if target in hashtable: count += hashtable[target] hashtable[sum] += 1 return count

时间复杂度:O(N);

体会

前缀和是一种很常用的思想,要对触发它的条件敏感 连续子数组+和,也就是用在哪一种题型里;
其次,哈希表也要敏感,比如在一个题目中有两数之和,那就要去用哈希表,可以利用其containsKey函数检索,从而少一次for循环;而哈希表中value的值就由我们要获得什么决定,比如此题是获得子数组的个数,那value就是每个和的次数;比如我们要获得子数组的大小或者下标,那value就是元素的索引,对症下药。

相关题目

1. 两数之和
930. 和相同的二元子数组
724. 寻找数组的中心下标
1248. 统计「优美子数组」
974. 和可被 K 整除的子数组
523. 连续的子数组和


__EOF__

本文作者Curryxin
本文链接https://www.cnblogs.com/Curryxin/p/15022950.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   Curryxin  阅读(79)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
Live2D
欢迎阅读『【LeetCode】【前缀和】560. 和为K的子数组』
点击右上角即可分享
微信分享提示