作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/


题目地址:https://leetcode.com/problems/binary-subarrays-with-sum/description/

题目描述

In an array A of 0s and 1s, 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:

  1. A.length <= 30000
  2. 0 <= S <= A.length
  3. A[i] is either 0 or 1.

题目大意

求有多少个子区间的和是S.

解题方法

悲剧啊!周赛第二个题都没做出来。我的想法是双指针,用虫取法的方式去做,但是发现了,当一个区间的前面或者后面都有0的时候,这时候移动前后指针都能达到下一个状态的和也是S。然后我就在上面吊死了。真正的做法如下。

二分查找

这个题考的不是虫取法,题目为什么只给了0和1呢?因为我们每次遇到一个1,整体的和只会增加1,求和的时候不会出现负数,所以如果从左到右求和的过程中是个递增的。

下面的做法有点类似Two sum,最开始先使用一个求和数组保存求和的过程,然后对求和数组tsum做一个遍历,遍历的过程中过程中,使用tsum[i] - S,这个结果remain就是我们要找的前面的部分和。也就是说remain出现的次数就是以i结尾的子数组满足题意的个数。

所以,下面的工作是找到这个remain在tsum中出现了多少次。使用二分查找的lowwer_bound和upper_bound就可以了。需要注意的是有个测试用例全部是0,这个情况下,如果upper_bound就直接找到最右边界了,所以我们得限制一下,upper_bound的索引不能超过当前的i.

时间复杂度是O(NlogN),空间复杂度是O(N)。

class Solution(object):
def numSubarraysWithSum(self, A, S):
"""
:type A: List[int]
:type S: int
:rtype: int
"""
N = len(A)
tsum = [0] * (N + 1)
for i in range(1, N + 1):
tsum[i] = tsum[i - 1] + A[i - 1]
res = 0
for i in range(1, N + 1):
remain = tsum[i] - S
if remain < 0:
continue
left = bisect.bisect_left(tsum, remain)
right = bisect.bisect_right(tsum, remain)
right = min(i, right)
res += right - left
return res

字典

在上面的做法中,我们想到了要查找remain出现了多少次,那么我们肯定想起来了使用字典啊!如果用字典的话不能直接先求所有的累计和,然后统计每个和出现了多少次,因为那样的话对全0的输入又蒙了!所以我们需要知道截止到某个位置的时候,当前的和减去S已经出现了多少次。所以这个字典是保存每个和已经出现的次数的!

使用一个字典保存数组某个位置之前的数组和,然后遍历数组求和,这样当我们求到一个位置的和的时候,向前找sum-k是否在数组中,如果在的话,更新结果为之前的结果+1。同时,当前这个sum出现的次数就多了一次。

560. Subarray Sum Equals K几乎一模一样的题目,为什么就是不会做呢?

class Solution(object):
def numSubarraysWithSum(self, A, S):
"""
:type A: List[int]
:type S: int
:rtype: int
"""
N = len(A)
res = 0
preS = 0
count = collections.Counter({0 : 1})
for i in range(1, N + 1):
preS += A[i - 1]
res += count[preS - S]
count[preS] += 1
return res

相似题目

560. Subarray Sum Equals K

参考资料

https://leetcode.com/problems/binary-subarrays-with-sum/discuss/186683/C++JavaPython-Straight-Forward

日期

2018 年 10 月 28 日 —— 啊,悲伤的周赛

【LeetCode】930. Binary Subarrays With Sum 解题报告(Python)的更多相关文章

  1. [LeetCode] 930. Binary Subarrays With Sum 二元子数组之和

    In an array A of 0s and 1s, how many non-empty subarrays have sum S? Example 1: Input: A = [1,0,1,0, ...

  2. LeetCode 930. Binary Subarrays With Sum

    原题链接在这里:https://leetcode.com/problems/binary-subarrays-with-sum/ 题目: In an array A of 0s and 1s, how ...

  3. 【LeetCode】829. Consecutive Numbers Sum 解题报告(C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 数学方法 日期 题目地址:https://leetc ...

  4. 【LeetCode】94. Binary Tree Inorder Traversal 解题报告(Python&C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 解题方法 递归 迭代 日期 题目地址:https://leetcode.c ...

  5. 【LeetCode】64. Minimum Path Sum 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...

  6. LeetCode: Unique Binary Search Trees II 解题报告

    Unique Binary Search Trees II Given n, generate all structurally unique BST's (binary search trees) ...

  7. 【LeetCode】784. Letter Case Permutation 解题报告 (Python&C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 回溯法 循环 日期 题目地址:https://leet ...

  8. 【LeetCode】206. Reverse Linked List 解题报告(Python&C++&java)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 迭代 递归 日期 [LeetCode] 题目地址:h ...

  9. LeetCode 2 Add Two Sum 解题报告

    LeetCode 2 Add Two Sum 解题报告 LeetCode第二题 Add Two Sum 首先我们看题目要求: You are given two linked lists repres ...

随机推荐

  1. Linux—Linux系统目录结构

    登录系统后,在当前命令窗口下输入命令:  ls /  你会看到如下图所示: 树状目录结构: 以下是对这些目录的解释: /bin:bin是Binary的缩写, 这个目录存放着最经常使用的命令. /boo ...

  2. Perl if条件判断

    Perl 条件语句是通过一条或多条语句的执行结果(True或者False)来决定执行的代码块. 条件判断常用: True         #布尔值 not True   #布尔值 ! True    ...

  3. php导出pdf,dompdf中文字体乱码解决办法(特别是代码迁移引起的乱码)

    dompdf\lib\fonts\dompdf_font_family_cache.php记住这个文件里面存放的是字体生成的缓存,迁移时如果覆盖了这个文件会导致乱码而且很难找到出错的地方,相信我... ...

  4. 寻找pair

    给定n个整数使其两两组合成一对pair,例如给定 1 ,2 可以组成的pair为(1,1),(1,2),(2,1),(2,2),然后在这些pair中寻找第k小的pair. 输入第一行包含两个数字,第一 ...

  5. Linux磁盘分区(二)之挂载卸载常用命令

    Linux磁盘分区(二)之挂载卸载常用命令 转自:https://blog.csdn.net/qq_36183935/article/details/81053383           https: ...

  6. oracle 日期语言格式化

    TO_DATE ('17-JUN-87', 'dd-mm-yy', 'NLS_DATE_LANGUAGE = American')

  7. Spring(4):Mybatis和Spring整合

    第一步:创建数据库 MySQL代码 1 CREATE DATABASE `mybatis` ; 2 3 USE `mybatis`; 4 5 CREATE TABLE `user` ( 6 `id` ...

  8. BigDecimal 计算注意事项

    BigDecimal 在进行除法运算(divide)时一定要注意:如果被除数为变量,一定要指定精度 和 舍入模式,否则会报:Non-terminating decimal expansion; no ...

  9. 02 - Vue3 UI Framework - 顶部边栏

    顶部边栏比较简单,而且首页和文档页都需要,所以我们先从顶部边栏做起 前文回顾点击 这里 返回阅读列表点击 这里 初始化 首先,在 components 文件夹下,创建一个 vue 组件,命名为 Top ...

  10. Service Worker的应用

    Service Worker的应用 Service worker本质上充当Web应用程序.浏览器与网络(可用时)之间的代理服务器,这个API旨在创建有效的离线体验,它会拦截网络请求并根据网络是否可用来 ...