[LeetCode] 930. Binary Subarrays With Sum 二元子数组之和
In an array `A` of `0`s and `1`s, how many non-empty subarrays have sum `S`?
Example 1:
Input: A = [1,0,1,0,1], S = 2
Output: 4
Explanation:
The 4 subarrays are bolded below:
[1,0,1,0,1]
[1,0,1,0,1]
[1,0,1,0,1]
[1,0,1,0,1]
Note:
A.length <= 300000 <= S <= A.lengthA[i]is either0or1.
这道题给了我们一个只由0和1组成的数组A,还有一个整数S,问数组A中有多少个子数组使得其和正好为S。博主最先没看清题意,以为是按二进制数算的,但是看了例子之后才发现,其实只是单纯的求和而已。那么马上就想着应该是要建立累加和数组的,然后遍历所有的子数组之和,但是这个遍历的过程还是平方级的复杂度,这道题的 OJ 卡的比较严格,只放行线性的时间复杂度。所以这种遍历方式是不行的,但仍需要利用累加和的思路,具体的方法是在遍历的过程中使用一个变量 curSum 来记录当前的累加和,同时使用一个 HashMap,用来映射某个累加出现的次数,初始化需要放入 {0,1} 这个映射对儿,后面会讲解原因。在遍历数组的A的时候,对于每个遇到
的数字 num,都加入累加和 curSum 中,然后看若 curSum-S 这个数有映射值的话,那么说明就存在 m[curSum-S] 个符合题意的子数组,应该加入到结果 res 中,假如 curSum 正好等于S,即 curSum-S=0 的时候,此时说明从开头到当前位置正好是符合题目要求的子数组,现在明白刚开始为啥要加入 {0,1} 这个映射对儿了吧,就是为了处理这种情况。然后此时 curSum 的映射值自增1即可。其实这道题的解法思路跟之前那道 [Contiguous Array](https://www.cnblogs.com/grandyang/p/6529857.html) 是一样的,那道题是让找0和1个数相同的子数组,这里让找和为S的子数组,都可以用一个套路来解题,参见代码如下:
解法一:
class Solution {
public:
int numSubarraysWithSum(vector<int>& A, int S) {
int res = 0, curSum = 0;
unordered_map<int, int> m{{0, 1}};
for (int num : A) {
curSum += num;
res += m[curSum - S];
++m[curSum];
}
return res;
}
};
我们也可以使用滑动窗口 Sliding Window 来做,也是线性的时间复杂度,其实还是利用到了累计和的思想,不过这个累加和不是从开头到当前位置之和,而是这个滑动窗口内数字之和,这 make sense 吧,因为只要这个滑动窗口内数字之和正好等于S了,即是符合题意的一个子数组。遍历数组A,将当前数字加入 sum 中,然后看假如此时 sum 大于S了,则要进行收缩窗口操作,左边界 left 右移,并且 sum 要减去这个移出窗口的数字,当循环退出后,假如此时 sum 小于S了,说明当前没有子数组之和正好等于S,若 sum 等于S了,则结果 res 自增1。此时还需要考虑一种情况,就是当窗口左边有连续0的时候,因为0并不影响 sum,但是却要算作不同的子数组,所以要统计左起连续0的个数,并且加到结果 res 中即可,参见代码如下:
解法二:
class Solution {
public:
int numSubarraysWithSum(vector<int>& A, int S) {
int res = 0, sum = 0, left = 0, n = A.size();
for (int i = 0; i < n; ++i) {
sum += A[i];
while (left < i && sum > S) sum -= A[left++];
if (sum < S) continue;
if (sum == S) ++res;
for (int j = left; j < i && A[j] == 0; ++j) {
++res;
}
}
return res;
}
};
Github 同步地址:
https://github.com/grandyang/leetcode/issues/930
参考资料:
https://leetcode.com/problems/binary-subarrays-with-sum/
https://leetcode.com/problems/binary-subarrays-with-sum/discuss/276976/C%2B%2B
[LeetCode All in One 题目讲解汇总(持续更新中...)](https://www.cnblogs.com/grandyang/p/4606334.html)
[LeetCode] 930. Binary Subarrays With Sum 二元子数组之和的更多相关文章
- [LeetCode] 209. Minimum Size Subarray Sum 最短子数组之和
Given an array of n positive integers and a positive integer s, find the minimal length of a contigu ...
- LeetCode 930. Binary Subarrays With Sum
原题链接在这里:https://leetcode.com/problems/binary-subarrays-with-sum/ 题目: In an array A of 0s and 1s, how ...
- [LeetCode] Minimum Size Subarray Sum 最短子数组之和
Given an array of n positive integers and a positive integer s, find the minimal length of a subarra ...
- Minimum Size Subarray Sum 最短子数组之和
题意 Given an array of n positive integers and a positive integer s, find the minimal length of a suba ...
- 【LeetCode】930. Binary Subarrays With Sum 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 二分查找 字典 相似题目 参考资料 日期 题目地址: ...
- [LintCode] Continuous Subarray Sum 连续子数组之和
Given an integer array, find a continuous subarray where the sum of numbers is the biggest. Your cod ...
- lintcode :continuous subarray sum 连续子数组之和
题目 连续子数组求和 给定一个整数数组,请找出一个连续子数组,使得该子数组的和最大.输出答案时,请分别返回第一个数字和最后一个数字的值.(如果两个相同的答案,请返回其中任意一个) 样例 给定 [-3, ...
- lintcode:子数组之和为0
题目: 子数组之和 给定一个整数数组,找到和为零的子数组.你的代码应该返回满足要求的子数组的起始位置和结束位置 样例 给出[-3, 1, 2, -3, 4],返回[0, 2] 或者 [1, 3]. 解 ...
- 求数组的子数组之和的最大值III(循环数组)
新的要求:一维数组改成循环数组,只是涉及简单算法,只是拿了小数做测试 想法:从文件读取数组,然后新建数组,将文件读取的数组在新数组中做一下连接,成为二倍长度的数组,然后再遍历,将每次遍历的子数组的和存 ...
随机推荐
- web前端面试第一次[javascript函数和方法的区别]
//函数 function f1(){ console.log("我是函数"); } //调用函数 f1(); //创建一个空对象 var obj = {} //把函数定义到对象里 ...
- Jsp和Servlet关系
为什么会出现Jsp? 其实对于服务器来说它只认识Servlet,我们完全可以在Servlet用resp.getWriter().write("");画出网页的界面,但是仅仅一个很简 ...
- 本周总结(19年暑假)—— Part7
日期:2019.8.25 博客期:113 星期日
- 随机序列[SHOI2016](找规律+线段树)
传送门 这道题的题意就是给你n个数让你在每个数之间插入+.-.*三种运算符中的一种,然后算出一个答案,再把答案加起来. 这题肯定是不能暴力的(题目都告诉你了由3n-1种结果).我们先从小的情况枚举找一 ...
- (3)LoraWAN:链路控制、SF BW CR
三.Introduction on LoRaWAN options 本文件描述了一种用于可为移动的或固定在一个固定位置的电池供电的终端设备而优化的LoRaWAN™网络协议.LORA™是一个由Semte ...
- 如何解决ajax跨域请求?
1.什么是跨域? a.域名不同 b.域名相同,端口不同 注:只有域名相同,端口相同时,才可以访问数据 可以使用jsonp解决ajax跨域请求的问题. 2.什么是jsonp? Jsonp其实就是一个跨域 ...
- JavaWeb--概述
1.Java Web应用由一组Servlet.HTML页.类以及其他可以被绑定的资源构成.它可以在何种供应商提供的实现Servlet规范的Servlet容器中运行: 2.Java Web应用中包含如下 ...
- 075、Java面向对象之定义匿名对象
01.代码如下: package TIANPAN; class Book { // 定义一个新的类 private String title; // 书的名字 private double price ...
- 几种编辑器的markdown-toc生成目录在github上的表现
Vscode vscode的markdown-toc插件的实现是比较好的, 目前发现的问题就只有在自动生成带链接目录的时候无法正确识别和生成一些特殊的字符. 例如: ▶ 这导致在标题中不能加入特殊字符 ...
- leetcode142 Linked List Cycle II
""" Given a linked list, return the node where the cycle begins. If there is no cycle ...