作者: 负雪明烛
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. arm三大编译器的不同选择编译

    ARM 系列目前支持三大主流的工具链,即ARM RealView (armcc), IAR EWARM (iccarm), and GNU Compiler Collection (gcc).     ...

  2. C语言中的指针的小标可以是负数

    首先,创建一个正常的数组 int A[20];.然后用指针指向其中间的元素 int *A2 = &(A[10]); 这样,A2[-10 ... 9] 就是一个可用的有效范围了. 1 2 3 4 ...

  3. Spark(二十)【SparkSQL将CSV导入Kudu】

    目录 SparkSql 将CSV导入kudu pom 依赖 scala 代码 启动脚本 SparkSql 将CSV导入kudu pom 依赖 <properties> <spark. ...

  4. CORS 如果需要指定多个域名怎么办

    CORS 通过控制 Access-Control-Allow-Origin 控制哪些域名可以共享资源,取值如下 Access-Control-Allow-Origin: <origin> ...

  5. 【c++】解析多文件编程的原理

    其实一直搞不懂为什么头文件和其他cpp文件之间的关系,今晚索性一下整明白 [c++]解析多文件编程的原理 a.cpp #include<stdio.h> int main(){ a(); ...

  6. 如何启动、关闭和设置ubuntu防火墙 (转载)

    引自:http://www.cnblogs.com/jiangyao/archive/2010/05/19/1738909.html 由于LInux原始的防火墙工具iptables过于繁琐,所以ubu ...

  7. 【leetocode】55. Jump Game

    You are given an integer array nums. You are initially positioned at the array's first index, and ea ...

  8. OC-私有方法,构造方法,类的本质及启动过程

    总结 标号 主题 内容 一 OC的私有方法 私有变量/私有方法 二 @property 概念/基本使用/寻找方法的过程/查找顺序 三 @synthesize @synthesize概念/基本使用/注意 ...

  9. linux 加密安全之AWK

    密钥 密钥一般是一串字符串或数字,在加密或者解密时传递给加密或者解密算法,以使算法能够正确对明文加密或密文解密. 加密算法 已知的加密算法有对称和非对称加密,也就是说你想进行加解密操作的时候需要具备密 ...

  10. FindUserByPageServlet

    package com.hopetesting.web.servlet;import com.hopetesting.domain.PageBean;import com.hopetesting.do ...