560.和为k的数组
1.题目介绍
给你一个整数数组 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
2.题解
请注意题目中要求的连续非空序列,要求1.连续 2.非空!!!
2.1 枚举(O(n^2))
思路
最简单的思路是利用双重循环确定数组的开头和结尾,在利用一重循环来进行遍历相加
int count = 0;
for (int start = 0; start <= nums.size(); start++)
{
for (int end = start; end <= nums.size(); end++)
{
int sum = 0;
for (int i = start; i <= end; i++)
sum += nums[i];
if (sum == k) count++;
}
}
但是这里的时间复杂度达到了O(n^3),必定会超过限制,所以我们进行了一些优化
还是双重循环遍历,确定数组的两个端点
但每次并非从前向后,而是从后向前挨个相加检查。
start确定遍历子数组的右端点,这里end为何不是从0开始,而是从start开始呢?
这样有一个什么好处呢,就是我们每次都有着[j,i]的和
只要再加上nums[j-1],就可以再得到[j-1,i]。
如果end从0开始,其实就和上面的三重循环遍历没有区别了
题解
注意这里找到 sum == k的时候,不可以直接break,因为举个例子[-1,1,0] k = 0; 这时候start指向0这个数,发现sum = k直接break,子数组[-1,1,0]也满足条件但是没有算上!!!
class Solution {
public:
int subarraySum(vector<int>& nums, int k) {
int count = 0;
for (int start = 0; start < nums.size(); start++) {
int sum = 0;
for (int end = start; end >= 0; end--) {
sum += nums[end];
if (sum == k) {
count++;
}
}
}
return count;
}
};
2.2 前缀和 + 哈希表优化
思路
关于前缀和是啥,请参考:前缀和
即 存在:preSum[i] = preSum[i-1] + nums[i]
前缀和 就是从 nums 数组中的第 0 位置开始,累加到第 i 位置的结果,我们常把这个结果保存到数组 preSum 中,记为 preSum[i]。
降二重循环为一重循环:
我们可以基于方法一利用数据结构进行进一步的优化,我们知道方法一的瓶颈在于对每个 i,我们需要枚举所有的 j 来判断是否符合条件,所以可以优化为一重循环吗?
我们既然选用一重循环,就面临一个问题,我们只能确定一个参数,这里我们肯定选择区间的右端点,这样的话我们怎么知道其与另一端点构成的子数组和呢?
这里我们利用前缀和的思路去做即可,即我们需要一个数组或者哈希表来保存之前求得的和,即[0,i-1]的和。
这里还有一个问题:子数组可能不是从下标0开始,也有可能是[j,i], 也就是 preSum[i] - preSum[j] = k;
那换个思路是不是我只要用哈希表存储了[0,i-1]每个0开始子数组{如[0,0],[0,1],[0,2]...}的前缀和和其出现次数,
并且加上一个用于表示[0,i]这个数组的键值对{0,1} [preSum[i] -preSum[0]表示的是[1,i],这里我必须加上这个键值对,preSum[i]-0表示的才是[0,i]的值]。
在得到preSum[i] = preSum[i-1] + nums[i]后,由preSum[i] - preSum[j] = k;演变为preSum[j] = preSum[i] - k; 寻找哈希表中值为preSum[i] - k的存在及其出现次数,若存在,将count加上出现次数;不存在,继续遍历即可。
但我们再仔细想想,已经使用了哈希表存储了前缀和及其出现次数,我们还需要用preSum数组来存储前缀和吗?明显是不需要的,我们只需要维护一个前缀和变量pre即可
这里不使用数组存储也是考虑到数组无法快速记录出现次数的问题
class Solution {
public:
int subarraySum(vector<int>& nums, int k) {
unordered_map<int, int> mp;
int count = 0, pre = 0;
mp[0] = 1;
for (int i = 0; i < nums.size(); i++){
pre += nums[i];
if (mp.count(pre - k)) count += mp[pre-k];
mp[pre]++;
}
return count;
}
};
560.和为k的数组的更多相关文章
- 力扣 - 560. 和为K的子数组
目录 题目 思路1(前缀和) 代码 复杂度分析 思路2(前缀和+哈希表优化) 代码 复杂度分析 题目 560. 和为K的子数组 思路1(前缀和) 构建前缀和数组,可以快速计算任意区间的和 注意:计算区 ...
- 【LeetCode】560. 和为K的子数组
560. 和为K的子数组 知识点:数组:前缀和: 题目描述 给定一个整数数组和一个整数 k,你需要找到该数组中和为 k 的连续的子数组的个数. 示例 输入:nums = [1,1,1], k = 2 ...
- Java实现 LeetCode 560 和为K的子数组(某著名排序大法改编)
560. 和为K的子数组 给定一个整数数组和一个整数 k,你需要找到该数组中和为 k 的连续的子数组的个数. 示例 1 : 输入:nums = [1,1,1], k = 2 输出: 2 , [1,1] ...
- 转:最小区间:k个有序的数组,找到最小区间使k个数组中每个数组至少有一个数在区间中
转:http://www.itmian4.com/thread-6504-1-1.html 最小区间原题 k个有序的数组,找到最小的区间范围使得这k个数组中,每个数组至少有一个数字在这个区间范围内.比 ...
- Leetcode 560.和为k的子数组
和为k的子数组 给定一个整数数组和一个整数 k,你需要找到该数组中和为 k 的连续的子数组的个数. 示例 1 : 输入:nums = [1,1,1], k = 2 输出: 2 , [1,1] 与 [1 ...
- LeetCode 560. 和为K的子数组(Subarray Sum Equals K)
题目描述 给定一个整数数组和一个整数 k,你需要找到该数组中和为 k 的连续的子数组的个数. 示例 1 : 输入:nums = [1,1,1], k = 2 输出: 2 , [1,1] 与 [1,1] ...
- 560. 和为K的子数组
Q: A: 1.暴力找所有可能的子数组,n^2个子数组,最长长度n,则n ^3. 2.n^2解法 从1~n-1各起点开始,一直找到结尾,n^2 class Solution { public: int ...
- LeetCode——560. 和为K的子数组
给定一个整数数组和一个整数 k,你需要找到该数组中和为 k 的连续的子数组的个数. 示例 1 : 输入:nums = [1,1,1], k = 2 输出: 2 , [1,1] 与 [1,1] 为两种不 ...
- 力扣题解-560. 和为K的子数组
题目描述 给定一个整数数组和一个整数 k,你需要找到该数组中和为 k 的连续的子数组的个数. 示例 1 : 输入:nums = [1,1,1], k = 2 输出: 2 , [1,1] 与 [1,1] ...
- 力扣Leetcode 560. 和为K的子数组
和为K的子数组 给定一个整数数组和一个整数 k,你需要找到该数组中和为 k 的连续的子数组的个数. 示例 : 输入:nums = [1,1,1], k = 2 输出: 2 , [1,1] 与 [1,1 ...
随机推荐
- 36. 干货系列从零用Rust编写负载均衡及代理,内网穿透中内网代理的实现
wmproxy wmproxy已用Rust实现http/https代理, socks5代理, 反向代理, 静态文件服务器,四层TCP/UDP转发,七层负载均衡,内网穿透,后续将实现websocket代 ...
- python操作elasticsearch-全文检索、拼写纠错、补全提示
1.首先安装elasticsearch包 pip install elasticsearch (一般会包含新旧版本,如果想要特定的版本,比如5.x 可以在后面加5数字) ""&qu ...
- 华企盾DSC远程桌面、实时监控连接不上常见处理方法
1.检测策略是否勾选了远程桌面需要客户端确认或者勾选了客户端显示"允许远程维护"选项 2.检查客户端5097目录是否有MgrDll.dll.uvnserver.exe文件(是否被杀 ...
- 怎样在Facebook上开发客户
尽管Facebook的主打社交和娱乐,但它仍是一个有助于开发外贸客户的重要平台.通过利用Facebook的广告.社群.内容分享和直接沟通等功能,您可以扩大您的业务网络,找到更多的外贸客户,并促成国际贸 ...
- ElasticSearch之Index modules
索引的参数,分为两类: 静态参数,仅支持在创建索引时指定,或者关闭索引后指定. 动态参数,允许在索引工作期间指定或者修改. 静态参数 index.number_of_shards 默认值为1. 本参数 ...
- k8s卷管理-1
目录 卷管理-1 1. 本地存储 1.1 emptyDir 1.2 hostPath 网络存储 搭建NFS服务器 使用NFS网络存储 搭建iSCSI服务器 使用iSCSI网络存储 卷管理-1 我们之前 ...
- Volcano 监控设计解读,一看就懂
摘要:Volcano 方便AI,大数据,基因,渲染等诸多行业通用计算框架介入,提供高性能任务调度引擎,高性能异构芯片管理,高性能任务运行管理等能力. Volcano 是一个 Kubernetes 云原 ...
- Go语言逆向技术:常量字符串
摘要:Go语言源代码编译成二进制文件后,源代码中的字符串存放在哪里?是如何组织的? 本文分享自华为云社区<go语言逆向技术之---常量字符串解密>,作者:安全技术猿. Go语言源代码编译成 ...
- 接通率维持 66% 以上,为什么火山引擎 VeDI 能让企业智能外呼不再难?
更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 智能机器人在企业级市场的应用更加深入了. 随着人工智能技术的进一步发展,包括智能外呼.财务审核.自助客服等在内的智 ...
- Solon 小技巧收集 - 页面跳转(重定向)
@XMapping("/") public void jump(XContext ctx){ ctx.redirect("http://www.noear.org&quo ...