[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 <= 30000
0 <= S <= A.length
A[i]
is either0
or1
.
这道题给了我们一个只由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(循环数组)
新的要求:一维数组改成循环数组,只是涉及简单算法,只是拿了小数做测试 想法:从文件读取数组,然后新建数组,将文件读取的数组在新数组中做一下连接,成为二倍长度的数组,然后再遍历,将每次遍历的子数组的和存 ...
随机推荐
- Python查询Redis中的Key
今日,大哥让我查下项目的在线用户量,听到这个消息顿时懵逼了,在线用户量,这个该怎么查????想到项目中的登陆用户缓存信息Token都存放在Redis中,是不是可以根据Redis中Token的个数大致估 ...
- ubuntu14 安装Express及简单应用
参考资料 [1] 基于Express的Hello World实例 Express 是一个基于 Node.js 平台的极简.灵活的 web 应用开发框架. 1. 环境 工具名 版本 nodejs v11 ...
- Numpy 为运算
Numpy “bitwise_” 开头的函数是位运算函数: Numpy 位运算包括以下几个函数: 函数 描述 bitwise_and 对数组元素执行位与操作 bitwise_or 对数组元素执行 ...
- 吴裕雄 Bootstrap 前端框架开发——Bootstrap 辅助类:"text-info" 类的文本样式
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- 【剑指Offer面试编程题】题目1389:变态跳台阶--九度OJ
题目描述: 一只青蛙一次可以跳上1级台阶,也可以跳上2级--它也可以跳上n级.求该青蛙跳上一个n级的台阶总共有多少种跳法. 输入: 输入可能包含多个测试样例,对于每个测试案例, 输入包括一个整数n(1 ...
- python join 和setDaemon 简介
Python多线程编程时,经常会用到join()和setDaemon()方法 1.join ()方法:主线程A中,创建了子线程B,并且在主线程A中调用了B.join(),那么,主线程A会在调用的地方等 ...
- Day9 - C - Bookshelf 2 POJ - 3628
Farmer John recently bought another bookshelf for the cow library, but the shelf is getting filled u ...
- centos 安装 memcached
centos 安装 memcached 1. 安装依赖: libeventyum install libevent-devel 2. 获取最新版本wget http://memcached.org/l ...
- 【题集】k倍区间(抽屉原理)
例1:http://lx.lanqiao.cn/problem.page?gpid=T444 蓝桥杯 问题描述 给定一个长度为N的数列,A1, A2, ... AN,如果其中一段连续的子序列Ai, A ...
- Python测试进阶——(6)Bash脚本启动Python监控程序并传递PID
用HiBench执行Hadoop——Sort测试用例,进入 /HiBench-master/bin/workloads/micro/sort/hadoop 目录下,执行命令: [root@node1 ...